Compare commits

..

No commits in common. "master" and "v3.22.2" have entirely different histories.

112 changed files with 2797 additions and 3365 deletions

37
.github/ISSUE_TEMPLATE.md vendored Normal file
View File

@ -0,0 +1,37 @@
<!--
Questions:
https://groups.google.com/forum/#!forum/loopbackjs
https://gitter.im/strongloop/loopback
Immediate support:
https://strongloop.com/api-connect-faqs/
https://strongloop.com/node-js/subscription-plans/
-->
# Description/Steps to reproduce
<!--
If feature: A description of the feature
If bug: Steps to reproduce
-->
# Link to reproduction sandbox
<!--
Link to an app sandbox for reproduction
Note: Failure to provide a sandbox application for reproduction purposes will result in the issue being closed.
-->
# Expected result
<!--
Also include actual results if bug
-->
# Additional information
<!--
Copy+paste the output of these two commands:
node -e 'console.log(process.platform, process.arch, process.versions.node)'
npm ls --prod --depth 0 | grep loopback
-->

View File

@ -1,53 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
labels: bug
---
<!-- 🚨 STOP 🚨 STOP 🚨 STOP 🚨
Are you using LoopBack version 4? Please report the bug here:
https://github.com/strongloop/loopback-next/issues/new
HELP US HELP YOU, PLEASE
- Do a quick search to avoid duplicate issues
- Provide as much information as possible (reproduction sandbox, use case for features, etc.)
- Consider using a more suitable venue for questions such as Stack Overflow, Gitter, etc.
Please fill in the *entire* template below.
-->
## Steps to reproduce
<!-- Describe how to reproduce the issue -->
## Current Behavior
<!-- Describe the observed result -->
## Expected Behavior
<!-- Describe what did you expect instead, what is the desired outcome? -->
## Link to reproduction sandbox
<!--
See https://loopback.io/doc/en/contrib/Reporting-issues.html#loopback-3x-bugs
Note: Failure to provide a sandbox application for reproduction purposes will result in the issue being closed.
-->
## Additional information
<!--
Copy+paste the output of these two commands:
node -e 'console.log(process.platform, process.arch, process.versions.node)'
npm ls --prod --depth 0 | grep loopback
-->
## Related Issues
<!-- Did you find other bugs that looked similar? -->
_See [Reporting Issues](http://loopback.io/doc/en/contrib/Reporting-issues.html) for more tips on writing good issues_

View File

@ -1,34 +0,0 @@
---
name: Feature request
about: Suggest an idea for this project
labels: feature
---
<!-- 🚨 STOP 🚨 STOP 🚨 STOP 🚨
LoopBack version 3 is in LTS mode, we are not accepting new features.
We are actively developing version 4, you can find the new GitHub
repository here: https://github.com/strongloop/loopback-next
-->
## Suggestion
<!-- A summary of what you'd like to see added or changed -->
## Use Cases
<!--
What do you want to use this for?
What shortcomings exist with current approaches?
-->
## Examples
<!-- Show how this would be used and what the behavior would be -->
## Acceptance criteria
TBD - will be filled by the team.

View File

@ -1,27 +0,0 @@
---
name: Question
about: The issue tracker is not for questions. Please use Stack Overflow or other resources for help.
labels: question
---
<!-- 🚨 STOP 🚨 STOP 🚨 STOP 🚨
THE ISSUE TRACKER IS NOT FOR QUESTIONS.
DO NOT CREATE A NEW ISSUE TO ASK A QUESTION.
Please use one of the following resources for help:
**Questions**
- https://stackoverflow.com/tags/loopbackjs
- https://groups.google.com/forum/#!forum/loopbackjs
- https://gitter.im/strongloop/loopback
**Immediate support**
- https://strongloop.com/api-connect-faqs/
- https://strongloop.com/node-js/subscription-plans/
-->

View File

@ -1,16 +0,0 @@
blank_issues_enabled: false
contact_links:
- name: Report a security vulnerability
url: https://loopback.io/doc/en/contrib/Reporting-issues.html#security-issues
about: >
LoopBack 3 has reached End-of-Life. No new security fixes will be provided
or accepted.
Do not report security vulnerabilities using GitHub issues. Please send an
email to `reachsl@us.ibm.com` instead.
- name: Get help on StackOverflow
url: https://stackoverflow.com/tags/loopbackjs
about: Please ask and answer questions on StackOverflow.
- name: Join our mailing list
url: https://groups.google.com/forum/#!forum/loopbackjs
about: You can also post your question to our mailing list.

View File

@ -1,18 +1,25 @@
### Description
#### Related issues
<!--
Please provide a high-level description of the changes made by your pull request.
Please use the following link syntaxes:
Include references to all related GitHub issues and other pull requests, for example:
Fixes #123
Implements #254
See also #23
- connect to #49 (to reference issues in the current repository)
- connect to strongloop/loopback#49 (to reference issues in another repository)
-->
## Checklist
- connect to <link_to_referenced_issue>
👉 [Read and sign the CLA (Contributor License Agreement)](https://cla.strongloop.com/agreements/strongloop/loopback) 👈
### Checklist
<!--
- Please mark your choice with an "x" (i.e. [x], see
https://github.com/blog/1375-task-lists-in-gfm-issues-pulls-comments)
- PR's without test coverage will be closed.
-->
- [ ] `npm test` passes on your machine
- [ ] New tests added or existing tests modified to cover all changes
- [ ] Code conforms with the [style guide](https://loopback.io/doc/en/contrib/style-guide-es6.html)
- [ ] Commit messages are following our [guidelines](https://loopback.io/doc/en/contrib/git-commit-messages.html)
- [ ] Code conforms with the [style
guide](http://loopback.io/doc/en/contrib/style-guide.html)

2
.github/stale.yml vendored
View File

@ -7,6 +7,8 @@ exemptLabels:
- pinned
- security
- critical
- p1
- major
# Label to use when marking an issue as stale
staleLabel: stale
# Comment to post when marking an issue as stale. Set to `false` to disable

View File

@ -1,15 +1,22 @@
sudo: false
language: node_js
node_js:
- "6"
- "8"
- "10"
- "12"
- "14"
addons:
chrome: stable
after_success: npm run coverage
# see https://www.npmjs.com/package/phantomjs-prebuilt#continuous-integration
cache:
directories:
- travis_phantomjs
before_install:
- npm config set registry http://ci.strongloop.com:4873/
# Upgrade PhantomJS to v2.1.1.
- "export PHANTOMJS_VERSION=2.1.1"
- "export PATH=$PWD/travis_phantomjs/phantomjs-$PHANTOMJS_VERSION-linux-x86_64/bin:$PATH"
- "if [ $(phantomjs --version) != $PHANTOMJS_VERSION ]; then rm -rf $PWD/travis_phantomjs; mkdir -p $PWD/travis_phantomjs; fi"
- "if [ $(phantomjs --version) != $PHANTOMJS_VERSION ]; then wget https://github.com/Medium/phantomjs/releases/download/v$PHANTOMJS_VERSION/phantomjs-$PHANTOMJS_VERSION-linux-x86_64.tar.bz2 -O $PWD/travis_phantomjs/phantomjs-$PHANTOMJS_VERSION-linux-x86_64.tar.bz2; fi"
- "if [ $(phantomjs --version) != $PHANTOMJS_VERSION ]; then tar -xvf $PWD/travis_phantomjs/phantomjs-$PHANTOMJS_VERSION-linux-x86_64.tar.bz2 -C $PWD/travis_phantomjs; fi"
- "phantomjs --version"

View File

@ -1,151 +1,3 @@
2020-11-25, Version 3.28.0
==========================
* upgrade nodemailer to greater than 6.4.16 (jannyHou)
* chore: sync LoopBack 4 with Node.js v14 EOL (Rifa Achrinza)
* chore: add Node.js 14 to travis (Diana Lau)
* Remove "major" and "p1" from stalebot (Miroslav Bajtoš)
2020-03-06, Version 3.27.0
==========================
* Update LTS status in README (Miroslav Bajtoš)
* chore: update copyright year (Diana Lau)
* feat: change hasone relation error message (Sujesh T)
* chore: disable security issue reporting (Nora)
* chore: fix eslint violations (Nora)
* fixup! manual fixes (Miroslav Bajtoš)
* fixup! eslint --fix . (Miroslav Bajtoš)
* chore: update eslint & eslint-config to latest (Miroslav Bajtoš)
* chore: update dev-dependencies (Miroslav Bajtoš)
* chore: update chai to v4, dirty-chai to v2 (Miroslav Bajtoš)
* Updated "ismail" package to v3.2 (Stanislav Sarbinski)
* Introduce issue templates for bugs, features, etc. (Miroslav Bajtoš)
* Improve PULL_REQUEST_TEMPLATE (Miroslav Bajtoš)
* test: use Chromium (not Chrome) when available (Miroslav Bajtoš)
* test: disable Chrome sandboxing when inside Docker (Miroslav Bajtoš)
* test: switch from PhantomJS to HeadlessChrome (Miroslav Bajtoš)
2019-05-31, Version 3.26.0
==========================
* fix: disallow queries in username and email fields (Hage Yaapa)
* Ignore failing downstream dependencies (Miroslav Bajtoš)
* Upgrade nyc to version 14 (Miroslav Bajtoš)
* Update Karma dependencies to latest versions (Miroslav Bajtoš)
* Drop Node.js 6.x from the supported versions (Miroslav Bajtoš)
* Fix Model.exists() to work with remote connector (Maxim Sharai)
* chore: update copyrights years (Agnes Lin)
* Update LTS status (Diana Lau)
* Enable Node.js 12.x on Travis CI (Miroslav Bajtoš)
* chore: update copyright year (Diana Lau)
* chore: update LB3 EOL date (Diana Lau)
2019-03-15, Version 3.25.1
==========================
* Back-ticks added to highlight example JSON (Quentin Presley)
* Add same change to description for findOne (Quentin Presley)
* Update the description for persisted-models (Quentin Presley)
* handle $2b$ in hashed password check (Sylvain Dumont)
2019-02-05, Version 3.25.0
==========================
* Support middleware injected by AppDynamics. (Mike Li)
2019-01-11, Version 3.24.2
==========================
* Fix crash when modifying an unknown user (Matheus Horstmann)
2019-01-08, Version 3.24.1
==========================
* Update underscore.string to 3.3.5 (Francois)
* Fix: treat empty access token string as undefined (andrey-abramow)
2018-11-15, Version 3.24.0
==========================
* Set juggler options for remote calls (Raymond Feng)
* Speed up ACL tests by reducing saltWorkFactor (Miroslav Bajtoš)
2018-10-25, Version 3.23.2
==========================
* Fix ACL check to support model wildcard (Moshe Malka)
2018-10-18, Version 3.23.1
==========================
* README: highlight Active LTS at the top (Miroslav Bajtoš)
2018-10-09, Version 3.23.0
==========================
* Clear handler cache when a method is added/removed (Mohammed Essehemy)
* Add `options.preserveAccessTokens` (lchaglla)
* Update LB3 to be active LTS (Diana Lau)
* Fix ACL tests to wait until all assertions finish (Moshe Malka)
* chore: update to latest linting rules (virkt25)
2018-09-12, Version 3.22.3
==========================
* chore: use grunt to install optional phantomjs (virkt25)
* [WebFM] fr translation (candytangnb)
2018-08-29, Version 3.22.2
==========================

View File

@ -1,10 +1,10 @@
// Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Copyright IBM Corp. 2014,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
/* global module:false */
'use strict';
module.exports = function(grunt) {
// Do not report warnings from unit-tests exercising deprecated paths
process.env.NO_DEPRECATION = 'loopback';
@ -104,7 +104,7 @@ module.exports = function(grunt) {
karma: {
'unit-once': {
configFile: 'test/karma.conf.js',
browsers: ['ChromeDocker'],
browsers: ['PhantomJS'],
singleRun: true,
reporters: ['dots', 'junit'],
@ -218,8 +218,8 @@ module.exports = function(grunt) {
grunt.loadNpmTasks('grunt-karma');
grunt.registerTask('e2e-server', function() {
const done = this.async();
const app = require('./test/fixtures/e2e/app');
var done = this.async();
var app = require('./test/fixtures/e2e/app');
app.listen(0, function() {
process.env.PORT = this.address().port;
done();

View File

@ -4,22 +4,6 @@
[![Module LTS Adopted'](https://img.shields.io/badge/Module%20LTS-Adopted-brightgreen.svg?style=flat)](http://github.com/CloudNativeJS/ModuleLTS)
[![IBM Support](https://img.shields.io/badge/IBM%20Support-Frameworks-brightgreen.svg?style=flat)](http://ibm.biz/node-support)
**⚠️ LoopBack 3 has reached end of life. We are no longer accepting pull requests or providing
support for community users. The only exception is fixes for critical bugs and security
vulnerabilities provided as part of support for IBM API Connect customers.
We urge all LoopBack 3 users to migrate their applications to LoopBack 4 as soon as possible.
Learn more about
<a href="https://loopback.io/doc/en/contrib/Long-term-support.html">LoopBack's long term support policy.</a>
will be provided or accepted. (See
[Module Long Term Support Policy](#module-long-term-support-policy) below.)**
We urge all LoopBack 3 users to migrate their applications to LoopBack 4 as
soon as possible. Refer to our
[Migration Guide](https://loopback.io/doc/en/lb4/migration-overview.html)
for more information on how to upgrade.
## Overview
LoopBack is a highly-extensible, open-source Node.js framework that enables you to:
* Create dynamic end-to-end REST APIs with little or no coding.
@ -43,15 +27,12 @@ For more details, see [https://loopback.io/](https://loopback.io/).
## Module Long Term Support Policy
LoopBack 3.x has reached End-of-Life.
This module adopts the [Module Long Term Support (LTS)](http://github.com/CloudNativeJS/ModuleLTS) policy, with the following End Of Life (EOL) dates:
| Version | Status | Published | EOL |
| ---------- | --------------- | --------- | -------------------- |
| LoopBack 4 | Current | Oct 2018 | Apr 2023 _(minimum)_ |
| LoopBack 3 | End-of-Life | Dec 2016 | Dec 2020 |
| LoopBack 2 | End-of-Life | Jul 2014 | Apr 2019 |
| Module Version | Release Date | Minimum EOL | EOL With | Status |
|------------------|--------------|-------------|--------------|---------|
| 3.x.x | Sept 2016 | Dec 2019 | | Current |
| 2.x.x | July 2014 | Apr 2019 | Node.js 6.x | LTS |
Learn more about our LTS plan in [docs](https://loopback.io/doc/en/contrib/Long-term-support.html).

View File

@ -1,4 +1,4 @@
// Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Copyright IBM Corp. 2014,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
@ -8,11 +8,11 @@
*/
'use strict';
const g = require('../../lib/globalize');
const loopback = require('../../lib/loopback');
const assert = require('assert');
const uid = require('uid2');
const DEFAULT_TOKEN_LEN = 64;
var g = require('../../lib/globalize');
var loopback = require('../../lib/loopback');
var assert = require('assert');
var uid = require('uid2');
var DEFAULT_TOKEN_LEN = 64;
/**
* Token based authentication and access control.
@ -93,11 +93,11 @@ module.exports = function(AccessToken) {
*/
AccessToken.getIdForRequest = function(req, options) {
options = options || {};
let params = options.params || [];
let headers = options.headers || [];
let cookies = options.cookies || [];
let i = 0;
let length, id;
var params = options.params || [];
var headers = options.headers || [];
var cookies = options.cookies || [];
var i = 0;
var length, id;
// https://github.com/strongloop/loopback/issues/1326
if (options.searchDefaultTokenKeys !== false) {
@ -107,7 +107,7 @@ module.exports = function(AccessToken) {
}
for (length = params.length; i < length; i++) {
const param = params[i];
var param = params[i];
// replacement for deprecated req.param()
id = req.params && req.params[param] !== undefined ? req.params[param] :
req.body && req.body[param] !== undefined ? req.body[param] :
@ -125,16 +125,11 @@ module.exports = function(AccessToken) {
if (typeof id === 'string') {
// Add support for oAuth 2.0 bearer token
// http://tools.ietf.org/html/rfc6750
// To prevent Error: Model::findById requires the id argument
// with loopback-datasource-juggler 2.56.0+
if (id === '') continue;
if (id.indexOf('Bearer ') === 0) {
id = id.substring(7);
if (options.bearerTokenBase64Encoded) {
// Decode from base64
const buf = new Buffer(id, 'base64');
var buf = new Buffer(id, 'base64');
id = buf.toString('utf8');
}
} else if (/^Basic /i.test(id)) {
@ -147,7 +142,7 @@ module.exports = function(AccessToken) {
// "a2b2c3:" (curl http://a2b2c3@localhost:3000/)
// "token:a2b2c3" (curl http://token:a2b2c3@localhost:3000/)
// ":a2b2c3"
const parts = /^([^:]*):(.*)$/.exec(id);
var parts = /^([^:]*):(.*)$/.exec(id);
if (parts) {
id = parts[2].length > parts[1].length ? parts[2] : parts[1];
}
@ -186,7 +181,7 @@ module.exports = function(AccessToken) {
} else if (isValid) {
cb(null, token);
} else {
const e = new Error(g.f('Invalid Access Token'));
var e = new Error(g.f('Invalid Access Token'));
e.status = e.statusCode = 401;
e.code = 'INVALID_TOKEN';
cb(e);
@ -213,7 +208,7 @@ module.exports = function(AccessToken) {
options = {};
}
const id = this.getIdForRequest(req, options);
var id = this.getIdForRequest(req, options);
if (id) {
this.resolve(id, cb);
@ -233,15 +228,15 @@ module.exports = function(AccessToken) {
try {
assert(
this.created && typeof this.created.getTime === 'function',
'token.created must be a valid Date',
'token.created must be a valid Date'
);
assert(this.ttl !== 0, 'token.ttl must be not be 0');
assert(this.ttl, 'token.ttl must exist');
assert(this.ttl >= -1, 'token.ttl must be >= -1');
const AccessToken = this.constructor;
const userRelation = AccessToken.relations.user; // may not be set up
let User = userRelation && userRelation.modelTo;
var AccessToken = this.constructor;
var userRelation = AccessToken.relations.user; // may not be set up
var User = userRelation && userRelation.modelTo;
// redefine user model if accessToken's principalType is available
if (this.principalType) {
@ -253,13 +248,13 @@ module.exports = function(AccessToken) {
}
}
const now = Date.now();
const created = this.created.getTime();
const elapsedSeconds = (now - created) / 1000;
const secondsToLive = this.ttl;
const eternalTokensAllowed = !!(User && User.settings.allowEternalTokens);
const isEternalToken = secondsToLive === -1;
const isValid = isEternalToken ?
var now = Date.now();
var created = this.created.getTime();
var elapsedSeconds = (now - created) / 1000;
var secondsToLive = this.ttl;
var eternalTokensAllowed = !!(User && User.settings.allowEternalTokens);
var isEternalToken = secondsToLive === -1;
var isValid = isEternalToken ?
eternalTokensAllowed :
elapsedSeconds < secondsToLive;

View File

@ -1,4 +1,4 @@
// Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Copyright IBM Corp. 2014,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
@ -30,20 +30,20 @@
Map to oAuth 2.0 scopes
*/
const g = require('../../lib/globalize');
const loopback = require('../../lib/loopback');
const utils = require('../../lib/utils');
const async = require('async');
const extend = require('util')._extend;
const assert = require('assert');
const debug = require('debug')('loopback:security:acl');
var g = require('../../lib/globalize');
var loopback = require('../../lib/loopback');
var utils = require('../../lib/utils');
var async = require('async');
var extend = require('util')._extend;
var assert = require('assert');
var debug = require('debug')('loopback:security:acl');
const ctx = require('../../lib/access-context');
const AccessContext = ctx.AccessContext;
const Principal = ctx.Principal;
const AccessRequest = ctx.AccessRequest;
var ctx = require('../../lib/access-context');
var AccessContext = ctx.AccessContext;
var Principal = ctx.Principal;
var AccessRequest = ctx.AccessRequest;
const Role = loopback.Role;
var Role = loopback.Role;
assert(Role, 'Role model must be defined before ACL model');
/**
@ -107,18 +107,18 @@ module.exports = function(ACL) {
* @returns {Number}
*/
ACL.getMatchingScore = function getMatchingScore(rule, req) {
const props = ['model', 'property', 'accessType'];
let score = 0;
var props = ['model', 'property', 'accessType'];
var score = 0;
for (let i = 0; i < props.length; i++) {
for (var i = 0; i < props.length; i++) {
// Shift the score by 4 for each of the properties as the weight
score = score * 4;
const ruleValue = rule[props[i]] || ACL.ALL;
const requestedValue = req[props[i]] || ACL.ALL;
const isMatchingMethodName = props[i] === 'property' &&
var ruleValue = rule[props[i]] || ACL.ALL;
var requestedValue = req[props[i]] || ACL.ALL;
var isMatchingMethodName = props[i] === 'property' &&
req.methodNames.indexOf(ruleValue) !== -1;
let isMatchingAccessType = ruleValue === requestedValue;
var isMatchingAccessType = ruleValue === requestedValue;
if (props[i] === 'accessType' && !isMatchingAccessType) {
switch (ruleValue) {
case ACL.EXECUTE:
@ -219,11 +219,11 @@ module.exports = function(ACL) {
acls = acls.sort(function(rule1, rule2) {
return ACL.getMatchingScore(rule2, req) - ACL.getMatchingScore(rule1, req);
});
let permission = ACL.DEFAULT;
let score = 0;
var permission = ACL.DEFAULT;
var score = 0;
for (let i = 0; i < acls.length; i++) {
const candidate = acls[i];
for (var i = 0; i < acls.length; i++) {
var candidate = acls[i];
score = ACL.getMatchingScore(candidate, req);
if (score < 0) {
// the highest scored ACL did not match
@ -239,8 +239,8 @@ module.exports = function(ACL) {
break;
}
// For wildcard match, find the strongest permission
const candidateOrder = AccessContext.permissionOrder[candidate.permission];
const permissionOrder = AccessContext.permissionOrder[permission];
var candidateOrder = AccessContext.permissionOrder[candidate.permission];
var permissionOrder = AccessContext.permissionOrder[permission];
if (candidateOrder > permissionOrder) {
permission = candidate.permission;
break;
@ -255,7 +255,7 @@ module.exports = function(ACL) {
debug('with score:', acl.score(req));
});
}
const res = new AccessRequest({
var res = new AccessRequest({
model: req.model,
property: req.property,
accessType: req.accessType,
@ -276,11 +276,11 @@ module.exports = function(ACL) {
* @return {Object[]} An array of ACLs
*/
ACL.getStaticACLs = function getStaticACLs(model, property) {
const modelClass = this.registry.findModel(model);
const staticACLs = [];
var modelClass = this.registry.findModel(model);
var staticACLs = [];
if (modelClass && modelClass.settings.acls) {
modelClass.settings.acls.forEach(function(acl) {
let prop = acl.property;
var prop = acl.property;
// We support static ACL property with array of string values.
if (Array.isArray(prop) && prop.indexOf(property) >= 0)
prop = property;
@ -296,7 +296,7 @@ module.exports = function(ACL) {
}
});
}
const prop = modelClass && (
var prop = modelClass && (
// regular property
modelClass.definition.properties[property] ||
// relation/scope
@ -339,17 +339,17 @@ module.exports = function(ACL) {
principalId = principalId.toString();
}
property = property || ACL.ALL;
const propertyQuery = (property === ACL.ALL) ? undefined : {inq: [property, ACL.ALL]};
var propertyQuery = (property === ACL.ALL) ? undefined : {inq: [property, ACL.ALL]};
accessType = accessType || ACL.ALL;
const accessTypeQuery = (accessType === ACL.ALL) ? undefined :
var accessTypeQuery = (accessType === ACL.ALL) ? undefined :
{inq: [accessType, ACL.ALL, ACL.EXECUTE]};
const req = new AccessRequest({model, property, accessType, registry: this.registry});
var req = new AccessRequest({model, property, accessType, registry: this.registry});
let acls = this.getStaticACLs(model, property);
var acls = this.getStaticACLs(model, property);
// resolved is an instance of AccessRequest
let resolved = this.resolvePermission(acls, req);
var resolved = this.resolvePermission(acls, req);
if (resolved && resolved.permission === ACL.DENY) {
debug('Permission denied by statically resolved permission');
@ -360,7 +360,7 @@ module.exports = function(ACL) {
return callback.promise;
}
const self = this;
var self = this;
this.find({where: {principalType: principalType, principalId: principalId,
model: model, property: propertyQuery, accessType: accessTypeQuery}},
function(err, dynACLs) {
@ -431,33 +431,33 @@ module.exports = function(ACL) {
*/
ACL.checkAccessForContext = function(context, callback) {
if (!callback) callback = utils.createPromiseCallback();
const self = this;
var self = this;
self.resolveRelatedModels();
const roleModel = self.roleModel;
var roleModel = self.roleModel;
if (!(context instanceof AccessContext)) {
context.registry = this.registry;
context = new AccessContext(context);
}
let authorizedRoles = {};
const remotingContext = context.remotingContext;
const model = context.model;
const modelDefaultPermission = model && model.settings.defaultPermission;
const property = context.property;
const accessType = context.accessType;
const modelName = context.modelName;
var authorizedRoles = {};
var remotingContext = context.remotingContext;
var model = context.model;
var modelDefaultPermission = model && model.settings.defaultPermission;
var property = context.property;
var accessType = context.accessType;
var modelName = context.modelName;
const methodNames = context.methodNames;
const propertyQuery = (property === ACL.ALL) ? undefined : {inq: methodNames.concat([ACL.ALL])};
var methodNames = context.methodNames;
var propertyQuery = (property === ACL.ALL) ? undefined : {inq: methodNames.concat([ACL.ALL])};
const accessTypeQuery = (accessType === ACL.ALL) ?
var accessTypeQuery = (accessType === ACL.ALL) ?
undefined :
(accessType === ACL.REPLICATE) ?
{inq: [ACL.REPLICATE, ACL.WRITE, ACL.ALL]} :
{inq: [accessType, ACL.ALL]};
const req = new AccessRequest({
var req = new AccessRequest({
model: modelName,
property,
accessType,
@ -475,29 +475,22 @@ module.exports = function(ACL) {
return callback.promise;
}
const effectiveACLs = [];
const staticACLs = self.getStaticACLs(model.modelName, property);
var effectiveACLs = [];
var staticACLs = self.getStaticACLs(model.modelName, property);
const query = {
where: {
model: {inq: [model.modelName, ACL.ALL]},
property: propertyQuery,
accessType: accessTypeQuery,
},
};
this.find(query, function(err, acls) {
this.find({where: {model: model.modelName, property: propertyQuery,
accessType: accessTypeQuery}}, function(err, acls) {
if (err) return callback(err);
const inRoleTasks = [];
var inRoleTasks = [];
acls = acls.concat(staticACLs);
acls.forEach(function(acl) {
// Check exact matches
for (let i = 0; i < context.principals.length; i++) {
const p = context.principals[i];
const typeMatch = p.type === acl.principalType;
const idMatch = String(p.id) === String(acl.principalId);
for (var i = 0; i < context.principals.length; i++) {
var p = context.principals[i];
var typeMatch = p.type === acl.principalType;
var idMatch = String(p.id) === String(acl.principalId);
if (typeMatch && idMatch) {
effectiveACLs.push(acl);
return;
@ -525,7 +518,7 @@ module.exports = function(ACL) {
if (err) return callback(err, null);
// resolved is an instance of AccessRequest
const resolved = self.resolvePermission(effectiveACLs, req);
var resolved = self.resolvePermission(effectiveACLs, req);
debug('---Resolved---');
resolved.debug();
@ -562,7 +555,7 @@ module.exports = function(ACL) {
ACL.checkAccessForToken = function(token, model, modelId, method, callback) {
assert(token, 'Access token is required');
if (!callback) callback = utils.createPromiseCallback();
const context = new AccessContext({
var context = new AccessContext({
registry: this.registry,
accessToken: token,
model: model,
@ -580,7 +573,7 @@ module.exports = function(ACL) {
ACL.resolveRelatedModels = function() {
if (!this.roleModel) {
const reg = this.registry;
var reg = this.registry;
this.roleModel = reg.getModelByType('Role');
this.roleMappingModel = reg.getModelByType('RoleMapping');
this.userModel = reg.getModelByType('User');
@ -607,25 +600,25 @@ module.exports = function(ACL) {
break;
case ACL.USER:
this.userModel.findOne(
{where: {or: [{username: id}, {email: id}, {id: id}]}}, cb,
{where: {or: [{username: id}, {email: id}, {id: id}]}}, cb
);
break;
case ACL.APP:
this.applicationModel.findOne(
{where: {or: [{name: id}, {email: id}, {id: id}]}}, cb,
{where: {or: [{name: id}, {email: id}, {id: id}]}}, cb
);
break;
default:
// try resolving a user model with a name matching the principalType
const userModel = this.registry.findModel(type);
var userModel = this.registry.findModel(type);
if (userModel) {
userModel.findOne(
{where: {or: [{username: id}, {email: id}, {id: id}]}},
cb,
cb
);
} else {
process.nextTick(function() {
const err = new Error(g.f('Invalid principal type: %s', type));
var err = new Error(g.f('Invalid principal type: %s', type));
err.statusCode = 400;
err.code = 'INVALID_PRINCIPAL_TYPE';
cb(err);
@ -646,7 +639,7 @@ module.exports = function(ACL) {
*/
ACL.isMappedToRole = function(principalType, principalId, role, cb) {
cb = cb || utils.createPromiseCallback();
const self = this;
var self = this;
this.resolvePrincipal(principalType, principalId,
function(err, principal) {
if (err) return cb(err);

View File

@ -1,26 +1,26 @@
// Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Copyright IBM Corp. 2014,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const assert = require('assert');
const utils = require('../../lib/utils');
var assert = require('assert');
var utils = require('../../lib/utils');
/*!
* Application management functions
*/
const crypto = require('crypto');
var crypto = require('crypto');
function generateKey(hmacKey, algorithm, encoding) {
hmacKey = hmacKey || 'loopback';
algorithm = algorithm || 'sha1';
encoding = encoding || 'hex';
const hmac = crypto.createHmac(algorithm, hmacKey);
const buf = crypto.randomBytes(32);
var hmac = crypto.createHmac(algorithm, hmacKey);
var buf = crypto.randomBytes(32);
hmac.update(buf);
const key = hmac.digest(encoding);
var key = hmac.digest(encoding);
return key;
}
@ -83,7 +83,7 @@ module.exports = function(Application) {
return next();
}
const app = ctx.instance;
var app = ctx.instance;
app.created = app.modified = new Date();
if (!app.id) {
app.id = generateKey('id', 'md5');
@ -115,8 +115,8 @@ module.exports = function(Application) {
}
cb = cb || utils.createPromiseCallback();
const props = {owner: owner, name: name};
for (const p in options) {
var props = {owner: owner, name: name};
for (var p in options) {
if (!(p in props)) {
props[p] = options[p];
}
@ -182,9 +182,9 @@ module.exports = function(Application) {
cb(err, null);
return cb.promise;
}
let result = null;
const keyNames = ['clientKey', 'javaScriptKey', 'restApiKey', 'windowsKey', 'masterKey'];
for (let i = 0; i < keyNames.length; i++) {
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,

View File

@ -1,4 +1,4 @@
// Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Copyright IBM Corp. 2014,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
@ -8,15 +8,15 @@
*/
'use strict';
const g = require('../../lib/globalize');
const PersistedModel = require('../../lib/loopback').PersistedModel;
const loopback = require('../../lib/loopback');
const utils = require('../../lib/utils');
const crypto = require('crypto');
const CJSON = {stringify: require('canonical-json')};
const async = require('async');
const assert = require('assert');
const debug = require('debug')('loopback:change');
var g = require('../../lib/globalize');
var PersistedModel = require('../../lib/loopback').PersistedModel;
var loopback = require('../../lib/loopback');
var utils = require('../../lib/utils');
var crypto = require('crypto');
var CJSON = {stringify: require('canonical-json')};
var async = require('async');
var assert = require('assert');
var debug = require('debug')('loopback:change');
/**
* Change list entry.
@ -58,10 +58,10 @@ module.exports = function(Change) {
Change.setup = function() {
PersistedModel.setup.call(this);
const Change = this;
var Change = this;
Change.getter.id = function() {
const hasModel = this.modelName && this.modelId;
var hasModel = this.modelName && this.modelId;
if (!hasModel) return null;
return Change.idForModel(this.modelName, this.modelId);
@ -80,12 +80,12 @@ module.exports = function(Change) {
*/
Change.rectifyModelChanges = function(modelName, modelIds, callback) {
const Change = this;
const errors = [];
var Change = this;
var errors = [];
callback = callback || utils.createPromiseCallback();
const tasks = modelIds.map(function(id) {
var tasks = modelIds.map(function(id) {
return function(cb) {
Change.findOrCreateChange(modelName, id, function(err, change) {
if (err) return next(err);
@ -106,13 +106,13 @@ module.exports = function(Change) {
async.parallel(tasks, function(err) {
if (err) return callback(err);
if (errors.length) {
const desc = errors
var desc = errors
.map(function(e) {
return '#' + e.modelId + ' - ' + e.toString();
})
.join('\n');
const msg = g.f('Cannot rectify %s changes:\n%s', modelName, desc);
var msg = g.f('Cannot rectify %s changes:\n%s', modelName, desc);
err = new Error(msg);
err.details = {errors: errors};
return callback(err);
@ -148,15 +148,15 @@ module.exports = function(Change) {
Change.findOrCreateChange = function(modelName, modelId, callback) {
assert(this.registry.findModel(modelName), modelName + ' does not exist');
callback = callback || utils.createPromiseCallback();
const id = this.idForModel(modelName, modelId);
const Change = this;
var id = this.idForModel(modelName, modelId);
var Change = this;
this.findById(id, function(err, change) {
if (err) return callback(err);
if (change) {
callback(null, change);
} else {
const ch = new Change({
var ch = new Change({
id: id,
modelName: modelName,
modelId: modelId,
@ -177,8 +177,8 @@ module.exports = function(Change) {
*/
Change.prototype.rectify = function(cb) {
const change = this;
const currentRev = this.rev;
var change = this;
var currentRev = this.rev;
change.debug('rectify change');
@ -216,7 +216,7 @@ module.exports = function(Change) {
function(err, checkpoint) {
if (err) return cb(err);
doRectify(checkpoint, rev);
},
}
);
}
@ -274,8 +274,8 @@ module.exports = function(Change) {
Change.prototype.currentRevision = function(cb) {
cb = cb || utils.createPromiseCallback();
const model = this.getModelCtor();
const id = this.getModelId();
var model = this.getModelCtor();
var id = this.getModelId();
model.findById(id, function(err, inst) {
if (err) return cb(err);
if (inst) {
@ -345,8 +345,8 @@ module.exports = function(Change) {
Change.prototype.equals = function(change) {
if (!change) return false;
const thisRev = this.rev || null;
const thatRev = change.rev || null;
var thisRev = this.rev || null;
var thatRev = change.rev || null;
return thisRev === thatRev;
};
@ -423,8 +423,8 @@ module.exports = function(Change) {
callback(null, {deltas: [], conflicts: []});
return callback.promise;
}
const remoteChangeIndex = {};
const modelIds = [];
var remoteChangeIndex = {};
var modelIds = [];
remoteChanges.forEach(function(ch) {
modelIds.push(ch.modelId);
remoteChangeIndex[ch.modelId] = new Change(ch);
@ -439,18 +439,18 @@ module.exports = function(Change) {
},
}, function(err, allLocalChanges) {
if (err) return callback(err);
const deltas = [];
const conflicts = [];
const localModelIds = [];
var deltas = [];
var conflicts = [];
var localModelIds = [];
const localChanges = allLocalChanges.filter(function(c) {
var localChanges = allLocalChanges.filter(function(c) {
return c.checkpoint >= since;
});
localChanges.forEach(function(localChange) {
localChange = new Change(localChange);
localModelIds.push(localChange.modelId);
const remoteChange = remoteChangeIndex[localChange.modelId];
var remoteChange = remoteChangeIndex[localChange.modelId];
if (remoteChange && !localChange.equals(remoteChange)) {
if (remoteChange.conflictsWith(localChange)) {
remoteChange.debug('remote conflict');
@ -466,8 +466,8 @@ module.exports = function(Change) {
modelIds.forEach(function(id) {
if (localModelIds.indexOf(id) !== -1) return;
const d = remoteChangeIndex[id];
const oldChange = allLocalChanges.filter(function(c) {
var d = remoteChangeIndex[id];
var oldChange = allLocalChanges.filter(function(c) {
return c.modelId === id;
})[0];
@ -495,14 +495,14 @@ module.exports = function(Change) {
Change.rectifyAll = function(cb) {
debug('rectify all');
const Change = this;
var Change = this;
// this should be optimized
this.find(function(err, changes) {
if (err) return cb(err);
async.each(
changes,
function(c, next) { c.rectify(next); },
cb,
cb
);
});
};
@ -513,7 +513,7 @@ module.exports = function(Change) {
*/
Change.getCheckpointModel = function() {
let checkpointModel = this.Checkpoint;
var checkpointModel = this.Checkpoint;
if (checkpointModel) return checkpointModel;
// FIXME(bajtos) This code creates multiple different models with the same
// model name, which is not a valid supported usage of juggler's API.
@ -526,7 +526,7 @@ module.exports = function(Change) {
Change.prototype.debug = function() {
if (debug.enabled) {
const args = Array.prototype.slice.call(arguments);
var args = Array.prototype.slice.call(arguments);
args[0] = args[0] + ' %s';
args.push(this.modelName);
debug.apply(this, args);
@ -551,16 +551,16 @@ module.exports = function(Change) {
Change.prototype.getModelId = function() {
// TODO(ritch) get rid of the need to create an instance
const Model = this.getModelCtor();
const id = this.modelId;
const m = new Model();
var Model = this.getModelCtor();
var id = this.modelId;
var m = new Model();
m.setId(id);
return m.getId();
};
Change.prototype.getModel = function(callback) {
const Model = this.constructor.settings.trackModel;
const id = this.getModelId();
var Model = this.constructor.settings.trackModel;
var id = this.getModelId();
Model.findById(id, callback);
};
@ -595,10 +595,10 @@ module.exports = function(Change) {
*/
Conflict.prototype.models = function(cb) {
const conflict = this;
const SourceModel = this.SourceModel;
const TargetModel = this.TargetModel;
let source, target;
var conflict = this;
var SourceModel = this.SourceModel;
var TargetModel = this.TargetModel;
var source, target;
async.parallel([
getSourceModel,
@ -637,8 +637,8 @@ module.exports = function(Change) {
*/
Conflict.prototype.changes = function(cb) {
const conflict = this;
let sourceChange, targetChange;
var conflict = this;
var sourceChange, targetChange;
async.parallel([
getSourceChange,
@ -646,7 +646,7 @@ module.exports = function(Change) {
], done);
function getSourceChange(cb) {
const SourceModel = conflict.SourceModel;
var SourceModel = conflict.SourceModel;
SourceModel.findLastChange(conflict.modelId, function(err, change) {
if (err) return cb(err);
sourceChange = change;
@ -655,7 +655,7 @@ module.exports = function(Change) {
}
function getTargetChange(cb) {
const TargetModel = conflict.TargetModel;
var TargetModel = conflict.TargetModel;
TargetModel.findLastChange(conflict.modelId, function(err, change) {
if (err) return cb(err);
targetChange = change;
@ -684,7 +684,7 @@ module.exports = function(Change) {
*/
Conflict.prototype.resolve = function(cb) {
const conflict = this;
var conflict = this;
conflict.TargetModel.findLastChange(
this.modelId,
function(err, targetChange) {
@ -692,9 +692,9 @@ module.exports = function(Change) {
conflict.SourceModel.updateLastChange(
conflict.modelId,
{prev: targetChange.rev},
cb,
cb
);
},
}
);
};
@ -718,16 +718,16 @@ module.exports = function(Change) {
* @param {Error} err
*/
Conflict.prototype.resolveUsingTarget = function(cb) {
const conflict = this;
var conflict = this;
conflict.models(function(err, source, target) {
if (err) return done(err);
if (target === null) {
return conflict.SourceModel.deleteById(conflict.modelId, done);
}
const inst = new conflict.SourceModel(
var inst = new conflict.SourceModel(
target.toObject(),
{persisted: true},
{persisted: true}
);
inst.save(done);
});
@ -751,7 +751,7 @@ module.exports = function(Change) {
* @returns {Conflict} A new Conflict instance.
*/
Conflict.prototype.swapParties = function() {
const Ctor = this.constructor;
var Ctor = this.constructor;
return new Ctor(this.modelId, this.TargetModel, this.SourceModel);
};
@ -765,14 +765,14 @@ module.exports = function(Change) {
*/
Conflict.prototype.resolveManually = function(data, cb) {
const conflict = this;
var conflict = this;
if (!data) {
return conflict.SourceModel.deleteById(conflict.modelId, done);
}
conflict.models(function(err, source, target) {
if (err) return done(err);
const inst = source || new conflict.SourceModel(target);
var inst = source || new conflict.SourceModel(target);
inst.setAttributes(data);
inst.save(function(err) {
if (err) return done(err);
@ -801,11 +801,11 @@ module.exports = function(Change) {
*/
Conflict.prototype.type = function(cb) {
const conflict = this;
var conflict = this;
this.changes(function(err, sourceChange, targetChange) {
if (err) return cb(err);
const sourceChangeType = sourceChange.type();
const targetChangeType = targetChange.type();
var sourceChangeType = sourceChange.type();
var targetChangeType = targetChange.type();
if (sourceChangeType === Change.UPDATE && targetChangeType === Change.UPDATE) {
return cb(null, Change.UPDATE);
}

View File

@ -1,4 +1,4 @@
// Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Copyright IBM Corp. 2014,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
@ -8,7 +8,7 @@
*/
'use strict';
const assert = require('assert');
var assert = require('assert');
/**
* Checkpoint list entry.
@ -35,15 +35,15 @@ module.exports = function(Checkpoint) {
* @param {Number} checkpoint The current checkpoint seq
*/
Checkpoint.current = function(cb) {
const Checkpoint = this;
var Checkpoint = this;
Checkpoint._getSingleton(function(err, cp) {
cb(err, cp.seq);
});
};
Checkpoint._getSingleton = function(cb) {
const query = {limit: 1}; // match all instances, return only one
const initialData = {seq: 1};
var query = {limit: 1}; // match all instances, return only one
var initialData = {seq: 1};
this.findOrCreate(query, initialData, cb);
};
@ -54,10 +54,10 @@ module.exports = function(Checkpoint) {
* @param {Object} checkpoint The current checkpoint
*/
Checkpoint.bumpLastSeq = function(cb) {
const Checkpoint = this;
var Checkpoint = this;
Checkpoint._getSingleton(function(err, cp) {
if (err) return cb(err);
const originalSeq = cp.seq;
var originalSeq = cp.seq;
cp.seq++;
// Update the checkpoint but only if it was not changed under our hands
Checkpoint.updateAll({id: cp.id, seq: originalSeq}, {seq: cp.seq}, function(err, info) {

View File

@ -1,10 +1,10 @@
// Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Copyright IBM Corp. 2014,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const g = require('../../lib/globalize');
var g = require('../../lib/globalize');
/**
* Email model. Extends LoopBack base [Model](#model-new-model).

View File

@ -1,10 +1,10 @@
// Copyright IBM Corp. 2016,2019. All Rights Reserved.
// Copyright IBM Corp. 2016,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const g = require('../../lib/globalize');
var g = require('../../lib/globalize');
/**
* Data model for key-value databases.
@ -226,17 +226,17 @@ function throwNotAttached(modelName, methodName) {
'The %s method has not been setup. ' +
'The {{KeyValueModel}} has not been correctly attached ' +
'to a {{DataSource}}!',
modelName, methodName, methodName,
modelName, methodName, methodName
));
}
function convertNullToNotFoundError(ctx, cb) {
if (ctx.result !== null) return cb();
const modelName = ctx.method.sharedClass.name;
const id = ctx.getArgByName('id');
const msg = g.f('Unknown "%s" {{key}} "%s".', modelName, id);
const error = new Error(msg);
var modelName = ctx.method.sharedClass.name;
var id = ctx.getArgByName('id');
var msg = g.f('Unknown "%s" {{key}} "%s".', modelName, id);
var error = new Error(msg);
error.statusCode = error.status = 404;
error.code = 'KEY_NOT_FOUND';
cb(error);

View File

@ -1,11 +1,11 @@
// Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Copyright IBM Corp. 2014,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const loopback = require('../../lib/loopback');
const utils = require('../../lib/utils');
var loopback = require('../../lib/loopback');
var utils = require('../../lib/utils');
/**
* The `RoleMapping` model extends from the built in `loopback.Model` type.
@ -26,7 +26,7 @@ module.exports = function(RoleMapping) {
RoleMapping.resolveRelatedModels = function() {
if (!this.userModel) {
const reg = this.registry;
var reg = this.registry;
this.roleModel = reg.getModelByType('Role');
this.userModel = reg.getModelByType('User');
this.applicationModel = reg.getModelByType('Application');
@ -44,7 +44,7 @@ module.exports = function(RoleMapping) {
this.constructor.resolveRelatedModels();
if (this.principalType === RoleMapping.APPLICATION) {
const applicationModel = this.constructor.applicationModel;
var applicationModel = this.constructor.applicationModel;
applicationModel.findById(this.principalId, callback);
} else {
process.nextTick(function() {
@ -63,7 +63,7 @@ module.exports = function(RoleMapping) {
RoleMapping.prototype.user = function(callback) {
callback = callback || utils.createPromiseCallback();
this.constructor.resolveRelatedModels();
let userModel;
var userModel;
if (this.principalType === RoleMapping.USER) {
userModel = this.constructor.userModel;
@ -94,7 +94,7 @@ module.exports = function(RoleMapping) {
this.constructor.resolveRelatedModels();
if (this.principalType === RoleMapping.ROLE) {
const roleModel = this.constructor.roleModel;
var roleModel = this.constructor.roleModel;
roleModel.findById(this.principalId, callback);
} else {
process.nextTick(function() {

View File

@ -1,18 +1,18 @@
// Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Copyright IBM Corp. 2014,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const loopback = require('../../lib/loopback');
const debug = require('debug')('loopback:security:role');
const assert = require('assert');
const async = require('async');
const utils = require('../../lib/utils');
const ctx = require('../../lib/access-context');
const AccessContext = ctx.AccessContext;
const Principal = ctx.Principal;
const RoleMapping = loopback.RoleMapping;
var loopback = require('../../lib/loopback');
var debug = require('debug')('loopback:security:role');
var assert = require('assert');
var async = require('async');
var utils = require('../../lib/utils');
var ctx = require('../../lib/access-context');
var AccessContext = ctx.AccessContext;
var Principal = ctx.Principal;
var RoleMapping = loopback.RoleMapping;
assert(RoleMapping, 'RoleMapping model must be defined before Role model');
@ -24,7 +24,7 @@ assert(RoleMapping, 'RoleMapping model must be defined before Role model');
module.exports = function(Role) {
Role.resolveRelatedModels = function() {
if (!this.userModel) {
const reg = this.registry;
var reg = this.registry;
this.roleMappingModel = reg.getModelByType('RoleMapping');
this.userModel = reg.getModelByType('User');
this.applicationModel = reg.getModelByType('Application');
@ -74,29 +74,29 @@ module.exports = function(Role) {
query.where = query.where || {};
roleModel.resolveRelatedModels();
const relsToModels = {
var relsToModels = {
users: roleModel.userModel,
applications: roleModel.applicationModel,
roles: roleModel,
};
const ACL = loopback.ACL;
const relsToTypes = {
var ACL = loopback.ACL;
var relsToTypes = {
users: ACL.USER,
applications: ACL.APP,
roles: ACL.ROLE,
};
let principalModel = relsToModels[rel];
let principalType = relsToTypes[rel];
var principalModel = relsToModels[rel];
var principalType = relsToTypes[rel];
// redefine user model and user type if user principalType is custom (available and not "USER")
const isCustomUserPrincipalType = rel === 'users' &&
var isCustomUserPrincipalType = rel === 'users' &&
query.where.principalType &&
query.where.principalType !== RoleMapping.USER;
if (isCustomUserPrincipalType) {
const registry = this.constructor.registry;
var registry = this.constructor.registry;
principalModel = registry.findModel(query.where.principalType);
principalType = query.where.principalType;
}
@ -133,10 +133,11 @@ module.exports = function(Role) {
roleModel.roleMappingModel.find({
where: {roleId: context.id, principalType: principalType},
}, function(err, mappings) {
var ids;
if (err) {
return callback(err);
}
const ids = mappings.map(function(m) {
ids = mappings.map(function(m) {
return m.principalId;
});
query.where = query.where || {};
@ -176,18 +177,18 @@ module.exports = function(Role) {
});
return;
}
const modelClass = context.model;
const modelId = context.modelId;
const user = context.getUser();
const userId = user && user.id;
const principalType = user && user.principalType;
const opts = {accessToken: context.accessToken};
var modelClass = context.model;
var modelId = context.modelId;
var user = context.getUser();
var userId = user && user.id;
var principalType = user && user.principalType;
var opts = {accessToken: context.accessToken};
Role.isOwner(modelClass, modelId, userId, principalType, opts, callback);
});
function isUserClass(modelClass) {
if (!modelClass) return false;
const User = modelClass.modelBuilder.models.User;
var User = modelClass.modelBuilder.models.User;
if (!User) return false;
return modelClass == User || modelClass.prototype instanceof User;
}
@ -221,7 +222,7 @@ module.exports = function(Role) {
* @promise
*/
Role.isOwner = function isOwner(modelClass, modelId, userId, principalType, options, callback) {
const _this = this;
var _this = this;
if (!callback && typeof options === 'function') {
callback = options;
@ -252,8 +253,8 @@ module.exports = function(Role) {
// 1. the app has a single user model and principalType is 'USER'
// 2. the app has multiple user models and principalType is not 'USER'
// multiple user models
const isMultipleUsers = _isMultipleUsers();
const isPrincipalTypeValid =
var isMultipleUsers = _isMultipleUsers();
var isPrincipalTypeValid =
(!isMultipleUsers && principalType === Principal.USER) ||
(isMultipleUsers && principalType !== Principal.USER);
@ -270,7 +271,7 @@ module.exports = function(Role) {
// Is the modelClass User or a subclass of User?
if (isUserClass(modelClass)) {
const userModelName = modelClass.modelName;
var userModelName = modelClass.modelName;
// matching ids is enough if principalType is USER or matches given user model name
if (principalType === Principal.USER || principalType === userModelName) {
process.nextTick(function() {
@ -288,7 +289,7 @@ module.exports = function(Role) {
}
debug('Model found: %j', inst);
const ownerRelations = modelClass.settings.ownerRelations;
var ownerRelations = modelClass.settings.ownerRelations;
if (!ownerRelations) {
return legacyOwnershipCheck(inst);
} else {
@ -307,24 +308,24 @@ module.exports = function(Role) {
// ownership check induced the whole isOwner() to resolve as false.
// This behaviour will be pruned at next LoopBack major release.
function legacyOwnershipCheck(inst) {
const ownerId = inst.userId || inst.owner;
var ownerId = inst.userId || inst.owner;
if (principalType === Principal.USER && ownerId && 'function' !== typeof ownerId) {
return callback(null, matches(ownerId, userId));
}
// Try to follow belongsTo
for (const r in modelClass.relations) {
const rel = modelClass.relations[r];
for (var r in modelClass.relations) {
var rel = modelClass.relations[r];
// relation should be belongsTo and target a User based class
const belongsToUser = rel.type === 'belongsTo' && isUserClass(rel.modelTo);
var belongsToUser = rel.type === 'belongsTo' && isUserClass(rel.modelTo);
if (!belongsToUser) {
continue;
}
// checking related user
const relatedUser = rel.modelTo;
const userModelName = relatedUser.modelName;
const isMultipleUsers = _isMultipleUsers(relatedUser);
var relatedUser = rel.modelTo;
var userModelName = relatedUser.modelName;
var isMultipleUsers = _isMultipleUsers(relatedUser);
// a relation can be considered for isOwner resolution if:
// 1. the app has a single user model and principalType is 'USER'
// 2. the app has multiple user models and principalType is the related user model name
@ -348,20 +349,20 @@ module.exports = function(Role) {
}
function checkOwnership(inst) {
const ownerRelations = inst.constructor.settings.ownerRelations;
var ownerRelations = inst.constructor.settings.ownerRelations;
// collecting related users
const relWithUsers = [];
for (const r in modelClass.relations) {
const rel = modelClass.relations[r];
var relWithUsers = [];
for (var r in modelClass.relations) {
var rel = modelClass.relations[r];
// relation should be belongsTo and target a User based class
if (rel.type !== 'belongsTo' || !isUserClass(rel.modelTo)) {
continue;
}
// checking related user
const relatedUser = rel.modelTo;
const userModelName = relatedUser.modelName;
const isMultipleUsers = _isMultipleUsers(relatedUser);
var relatedUser = rel.modelTo;
var userModelName = relatedUser.modelName;
var isMultipleUsers = _isMultipleUsers(relatedUser);
// a relation can be considered for isOwner resolution if:
// 1. the app has a single user model and principalType is 'USER'
// 2. the app has multiple user models and principalType is the related user model name
@ -402,8 +403,8 @@ module.exports = function(Role) {
// user model by type. The relation with AccessToken is used to check
// if polymorphism is used, and thus if multiple users.
function _isMultipleUsers(userModel) {
const oneOfUserModels = userModel || _this.registry.getModelByType('User');
const accessTokensRel = oneOfUserModels.relations.accessTokens;
var oneOfUserModels = userModel || _this.registry.getModelByType('User');
var accessTokensRel = oneOfUserModels.relations.accessTokens;
return !!(accessTokensRel && accessTokensRel.polymorphic);
}
};
@ -479,15 +480,15 @@ module.exports = function(Role) {
debug('isInRole(): %s', role);
context.debug();
const resolver = Role.resolvers[role];
var resolver = Role.resolvers[role];
if (resolver) {
debug('Custom resolver found for role %s', role);
const promise = resolver(role, context, callback);
var promise = resolver(role, context, callback);
if (promise && typeof promise.then === 'function') {
promise.then(
function(result) { callback(null, result); },
callback,
callback
);
}
return callback.promise;
@ -501,9 +502,9 @@ module.exports = function(Role) {
return callback.promise;
}
const inRole = context.principals.some(function(p) {
const principalType = p.type || undefined;
const principalId = p.id || undefined;
var inRole = context.principals.some(function(p) {
var principalType = p.type || undefined;
var principalId = p.id || undefined;
// Check if it's the same role
return principalType === RoleMapping.ROLE && principalId === role;
@ -517,7 +518,7 @@ module.exports = function(Role) {
return callback.promise;
}
const roleMappingModel = this.roleMappingModel;
var roleMappingModel = this.roleMappingModel;
this.findOne({where: {name: role}}, function(err, result) {
if (err) {
if (callback) callback(err);
@ -531,10 +532,10 @@ module.exports = function(Role) {
// Iterate through the list of principals
async.some(context.principals, function(p, done) {
const principalType = p.type || undefined;
let principalId = p.id || undefined;
const roleId = result.id.toString();
const principalIdIsString = typeof principalId === 'string';
var principalType = p.type || undefined;
var principalId = p.id || undefined;
var roleId = result.id.toString();
var principalIdIsString = typeof principalId === 'string';
if (principalId !== null && principalId !== undefined && !principalIdIsString) {
principalId = principalId.toString();
@ -584,18 +585,18 @@ module.exports = function(Role) {
if (!(context instanceof AccessContext)) {
context = new AccessContext(context);
}
const roles = [];
var roles = [];
this.resolveRelatedModels();
const addRole = function(role) {
var addRole = function(role) {
if (role && roles.indexOf(role) === -1) {
roles.push(role);
}
};
const self = this;
var self = this;
// Check against the smart roles
const inRoleTasks = [];
var inRoleTasks = [];
Object.keys(Role.resolvers).forEach(function(role) {
inRoleTasks.push(function(done) {
self.isInRole(role, context, function(err, inRole) {
@ -612,11 +613,11 @@ module.exports = function(Role) {
});
});
const roleMappingModel = this.roleMappingModel;
var roleMappingModel = this.roleMappingModel;
context.principals.forEach(function(p) {
// Check against the role mappings
const principalType = p.type || undefined;
let principalId = p.id == null ? undefined : p.id;
var principalType = p.type || undefined;
var principalId = p.id == null ? undefined : p.id;
if (typeof principalId !== 'string' && principalId != null) {
principalId = principalId.toString();
@ -630,7 +631,7 @@ module.exports = function(Role) {
if (principalType && principalId) {
// Please find() treat undefined matches all values
inRoleTasks.push(function(done) {
const filter = {where: {principalType: principalType, principalId: principalId}};
var filter = {where: {principalType: principalType, principalId: principalId}};
if (options.returnOnlyRoleNames === true) {
filter.include = ['role'];
}
@ -641,7 +642,7 @@ module.exports = function(Role) {
return;
}
mappings.forEach(function(m) {
let role;
var role;
if (options.returnOnlyRoleNames === true) {
role = m.toJSON().role.name;
} else {

View File

@ -1,11 +1,11 @@
// Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Copyright IBM Corp. 2014,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const assert = require('assert');
const loopback = require('../../lib/loopback');
var assert = require('assert');
var loopback = require('../../lib/loopback');
/**
* Resource owner grants/delegates permissions to client applications
@ -21,7 +21,7 @@ const loopback = require('../../lib/loopback');
module.exports = function(Scope) {
Scope.resolveRelatedModels = function() {
if (!this.aclModel) {
const reg = this.registry;
var reg = this.registry;
this.aclModel = reg.getModelByType(loopback.ACL);
}
};
@ -38,7 +38,7 @@ module.exports = function(Scope) {
*/
Scope.checkPermission = function(scope, model, property, accessType, callback) {
this.resolveRelatedModels();
const aclModel = this.aclModel;
var aclModel = this.aclModel;
assert(aclModel,
'ACL model must be defined before Scope.checkPermission is called');
@ -47,7 +47,7 @@ module.exports = function(Scope) {
if (callback) callback(err);
} else {
aclModel.checkPermission(
aclModel.SCOPE, scope.id, model, property, accessType, callback,
aclModel.SCOPE, scope.id, model, property, accessType, callback
);
}
});

View File

@ -1,4 +1,4 @@
// Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Copyright IBM Corp. 2014,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
@ -8,18 +8,18 @@
*/
'use strict';
const g = require('../../lib/globalize');
const isEmail = require('isemail');
const loopback = require('../../lib/loopback');
const utils = require('../../lib/utils');
const path = require('path');
const qs = require('querystring');
const SALT_WORK_FACTOR = 10;
const crypto = require('crypto');
var g = require('../../lib/globalize');
var isEmail = require('isemail');
var loopback = require('../../lib/loopback');
var utils = require('../../lib/utils');
var path = require('path');
var qs = require('querystring');
var SALT_WORK_FACTOR = 10;
var crypto = require('crypto');
// bcrypt's max length is 72 bytes;
// See https://github.com/kelektiv/node.bcrypt.js/blob/45f498ef6dc6e8234e58e07834ce06a50ff16352/src/node_blf.h#L59
const MAX_PASSWORD_LENGTH = 72;
let bcrypt;
var MAX_PASSWORD_LENGTH = 72;
var bcrypt;
try {
// Try the native module first
bcrypt = require('bcrypt');
@ -32,12 +32,12 @@ try {
bcrypt = require('bcryptjs');
}
const DEFAULT_TTL = 1209600; // 2 weeks in seconds
const DEFAULT_RESET_PW_TTL = 15 * 60; // 15 mins in seconds
const DEFAULT_MAX_TTL = 31556926; // 1 year in seconds
const assert = require('assert');
var DEFAULT_TTL = 1209600; // 2 weeks in seconds
var DEFAULT_RESET_PW_TTL = 15 * 60; // 15 mins in seconds
var DEFAULT_MAX_TTL = 31556926; // 1 year in seconds
var assert = require('assert');
const debug = require('debug')('loopback:user');
var debug = require('debug')('loopback:user');
/**
* Built-in User model.
@ -123,18 +123,18 @@ module.exports = function(User) {
tokenData = {};
}
const userSettings = this.constructor.settings;
var userSettings = this.constructor.settings;
tokenData.ttl = Math.min(tokenData.ttl || userSettings.ttl, userSettings.maxTTL);
this.accessTokens.create(tokenData, options, cb);
return cb.promise;
};
function splitPrincipal(name, realmDelimiter) {
const parts = [null, name];
var parts = [null, name];
if (!realmDelimiter) {
return parts;
}
const index = name.indexOf(realmDelimiter);
var index = name.indexOf(realmDelimiter);
if (index !== -1) {
parts[0] = name.substring(0, index);
parts[1] = name.substring(index + realmDelimiter.length);
@ -150,7 +150,7 @@ module.exports = function(User) {
* @returns {Object} The normalized credential object
*/
User.normalizeCredentials = function(credentials, realmRequired, realmDelimiter) {
const query = {};
var query = {};
credentials = credentials || {};
if (!realmRequired) {
if (credentials.email) {
@ -162,7 +162,7 @@ module.exports = function(User) {
if (credentials.realm) {
query.realm = credentials.realm;
}
let parts;
var parts;
if (credentials.email) {
parts = splitPrincipal(credentials.email, realmDelimiter);
query.email = parts[1];
@ -205,7 +205,7 @@ module.exports = function(User) {
*/
User.login = function(credentials, include, fn) {
const self = this;
var self = this;
if (typeof include === 'function') {
fn = include;
include = undefined;
@ -222,54 +222,33 @@ module.exports = function(User) {
include = include.toLowerCase();
}
let realmDelimiter;
var realmDelimiter;
// Check if realm is required
const realmRequired = !!(self.settings.realmRequired ||
var realmRequired = !!(self.settings.realmRequired ||
self.settings.realmDelimiter);
if (realmRequired) {
realmDelimiter = self.settings.realmDelimiter;
}
const query = self.normalizeCredentials(credentials, realmRequired,
var query = self.normalizeCredentials(credentials, realmRequired,
realmDelimiter);
if (realmRequired) {
if (!query.realm) {
const err1 = new Error(g.f('{{realm}} is required'));
err1.statusCode = 400;
err1.code = 'REALM_REQUIRED';
fn(err1);
return fn.promise;
} else if (typeof query.realm !== 'string') {
const err5 = new Error(g.f('Invalid realm'));
err5.statusCode = 400;
err5.code = 'INVALID_REALM';
fn(err5);
return fn.promise;
}
if (realmRequired && !query.realm) {
var err1 = new Error(g.f('{{realm}} is required'));
err1.statusCode = 400;
err1.code = 'REALM_REQUIRED';
fn(err1);
return fn.promise;
}
if (!query.email && !query.username) {
const err2 = new Error(g.f('{{username}} or {{email}} is required'));
var err2 = new Error(g.f('{{username}} or {{email}} is required'));
err2.statusCode = 400;
err2.code = 'USERNAME_EMAIL_REQUIRED';
fn(err2);
return fn.promise;
}
if (query.username && typeof query.username !== 'string') {
const err3 = new Error(g.f('Invalid username'));
err3.statusCode = 400;
err3.code = 'INVALID_USERNAME';
fn(err3);
return fn.promise;
} else if (query.email && typeof query.email !== 'string') {
const err4 = new Error(g.f('Invalid email'));
err4.statusCode = 400;
err4.code = 'INVALID_EMAIL';
fn(err4);
return fn.promise;
}
self.findOne({where: query}, function(err, user) {
const defaultError = new Error(g.f('login failed'));
var defaultError = new Error(g.f('login failed'));
defaultError.statusCode = 401;
defaultError.code = 'LOGIN_FAILED';
@ -344,7 +323,7 @@ module.exports = function(User) {
User.logout = function(tokenId, fn) {
fn = fn || utils.createPromiseCallback();
let err;
var err;
if (!tokenId) {
err = new Error(g.f('{{accessToken}} is required to logout'));
err.statusCode = 401;
@ -370,12 +349,12 @@ module.exports = function(User) {
// Do nothing when the access control was disabled for this user model.
if (!ctx.Model.relations.accessTokens) return next();
const AccessToken = ctx.Model.relations.accessTokens.modelTo;
const pkName = ctx.Model.definition.idName() || 'id';
var AccessToken = ctx.Model.relations.accessTokens.modelTo;
var pkName = ctx.Model.definition.idName() || 'id';
ctx.Model.find({where: ctx.where, fields: [pkName]}, function(err, list) {
if (err) return next(err);
const ids = list.map(function(u) { return u[pkName]; });
var ids = list.map(function(u) { return u[pkName]; });
ctx.where = {};
ctx.where[pkName] = {inq: ids};
@ -720,9 +699,9 @@ module.exports = function(User) {
}
cb = cb || utils.createPromiseCallback();
const user = this;
const userModel = this.constructor;
const registry = userModel.registry;
var user = this;
var userModel = this.constructor;
var registry = userModel.registry;
verifyOptions = Object.assign({}, verifyOptions);
// final assertion is performed once all options are assigned
assert(typeof verifyOptions === 'object',
@ -743,19 +722,19 @@ module.exports = function(User) {
verifyOptions.mailer = verifyOptions.mailer || userModel.email ||
registry.getModelByType(loopback.Email);
const pkName = userModel.definition.idName() || 'id';
var pkName = userModel.definition.idName() || 'id';
verifyOptions.redirect = verifyOptions.redirect || '/';
const defaultTemplate = path.join(__dirname, '..', '..', 'templates', 'verify.ejs');
var defaultTemplate = path.join(__dirname, '..', '..', 'templates', 'verify.ejs');
verifyOptions.template = path.resolve(verifyOptions.template || defaultTemplate);
verifyOptions.user = user;
verifyOptions.protocol = verifyOptions.protocol || 'http';
const app = userModel.app;
var app = userModel.app;
verifyOptions.host = verifyOptions.host || (app && app.get('host')) || 'localhost';
verifyOptions.port = verifyOptions.port || (app && app.get('port')) || 3000;
verifyOptions.restApiRoot = verifyOptions.restApiRoot || (app && app.get('restApiRoot')) || '/api';
const displayPort = (
var displayPort = (
(verifyOptions.protocol === 'http' && verifyOptions.port == '80') ||
(verifyOptions.protocol === 'https' && verifyOptions.port == '443')
) ? '' : ':' + verifyOptions.port;
@ -766,14 +745,14 @@ module.exports = function(User) {
throw new Error(
'Cannot build user verification URL, ' +
'the default confirm method is not public. ' +
'Please provide the URL in verifyOptions.verifyHref.',
'Please provide the URL in verifyOptions.verifyHref.'
);
}
const urlPath = joinUrlPath(
verifyOptions.restApiRoot,
userModel.http.path,
confirmMethod.http.path,
confirmMethod.http.path
);
verifyOptions.verifyHref =
@ -796,7 +775,7 @@ module.exports = function(User) {
assertVerifyOptions(verifyOptions);
// argument "options" is passed depending on verifyOptions.generateVerificationToken function requirements
const tokenGenerator = verifyOptions.generateVerificationToken;
var tokenGenerator = verifyOptions.generateVerificationToken;
if (tokenGenerator.length == 3) {
tokenGenerator(user, options, addTokenToUserAndSave);
} else {
@ -824,7 +803,7 @@ module.exports = function(User) {
verifyOptions.text = verifyOptions.text.replace(/\{href\}/g, verifyOptions.verifyHref);
// argument "options" is passed depending on templateFn function requirements
const templateFn = verifyOptions.templateFn;
var templateFn = verifyOptions.templateFn;
if (templateFn.length == 3) {
templateFn(verifyOptions, options, setHtmlContentAndSend);
} else {
@ -841,7 +820,7 @@ module.exports = function(User) {
delete verifyOptions.template;
// argument "options" is passed depending on Email.send function requirements
const Email = verifyOptions.mailer;
var Email = verifyOptions.mailer;
if (Email.send.length == 3) {
Email.send(verifyOptions, options, handleAfterSend);
} else {
@ -873,8 +852,8 @@ module.exports = function(User) {
}
function createVerificationEmailBody(verifyOptions, options, cb) {
const template = loopback.template(verifyOptions.template);
const body = template(verifyOptions);
var template = loopback.template(verifyOptions.template);
var body = template(verifyOptions);
cb(null, body);
}
@ -952,11 +931,11 @@ module.exports = function(User) {
User.resetPassword = function(options, cb) {
cb = cb || utils.createPromiseCallback();
const UserModel = this;
const ttl = UserModel.settings.resetPasswordTokenTTL || DEFAULT_RESET_PW_TTL;
var UserModel = this;
var ttl = UserModel.settings.resetPasswordTokenTTL || DEFAULT_RESET_PW_TTL;
options = options || {};
if (typeof options.email !== 'string') {
const err = new Error(g.f('Email is required'));
var err = new Error(g.f('Email is required'));
err.statusCode = 400;
err.code = 'EMAIL_REQUIRED';
cb(err);
@ -970,7 +949,7 @@ module.exports = function(User) {
} catch (err) {
return cb(err);
}
const where = {
var where = {
email: options.email,
};
if (options.realm) {
@ -1031,12 +1010,12 @@ module.exports = function(User) {
*/
User.hashPassword = function(plain) {
this.validatePassword(plain);
const salt = bcrypt.genSaltSync(this.settings.saltWorkFactor || SALT_WORK_FACTOR);
var salt = bcrypt.genSaltSync(this.settings.saltWorkFactor || SALT_WORK_FACTOR);
return bcrypt.hashSync(plain, salt);
};
User.validatePassword = function(plain) {
let err;
var err;
if (!plain || typeof plain !== 'string') {
err = new Error(g.f('Invalid password.'));
err.code = 'INVALID_PASSWORD';
@ -1045,7 +1024,7 @@ module.exports = function(User) {
}
// Bcrypt only supports up to 72 bytes; the rest is silently dropped.
const len = Buffer.byteLength(plain, 'utf8');
var len = Buffer.byteLength(plain, 'utf8');
if (len > MAX_PASSWORD_LENGTH) {
err = new Error(g.f('The password entered was too long. Max length is %d (entered %d)',
MAX_PASSWORD_LENGTH, len));
@ -1064,20 +1043,20 @@ module.exports = function(User) {
if (!Array.isArray(userIds) || !userIds.length)
return process.nextTick(cb);
const accessTokenRelation = this.relations.accessTokens;
var accessTokenRelation = this.relations.accessTokens;
if (!accessTokenRelation)
return process.nextTick(cb);
const AccessToken = accessTokenRelation.modelTo;
const query = {userId: {inq: userIds}};
const tokenPK = AccessToken.definition.idName() || 'id';
var AccessToken = accessTokenRelation.modelTo;
var query = {userId: {inq: userIds}};
var tokenPK = AccessToken.definition.idName() || 'id';
if (options.accessToken && tokenPK in options.accessToken) {
query[tokenPK] = {neq: options.accessToken[tokenPK]};
}
// add principalType in AccessToken.query if using polymorphic relations
// between AccessToken and User
const relatedUser = AccessToken.relations.user;
const isRelationPolymorphic = relatedUser && relatedUser.polymorphic &&
var relatedUser = AccessToken.relations.user;
var isRelationPolymorphic = relatedUser && relatedUser.polymorphic &&
!relatedUser.modelTo;
if (isRelationPolymorphic) {
query.principalType = this.modelName;
@ -1092,7 +1071,7 @@ module.exports = function(User) {
User.setup = function() {
// We need to call the base class's setup method
User.base.setup.call(this);
const UserModel = this;
var UserModel = this;
// max ttl
this.settings.maxTTL = this.settings.maxTTL || DEFAULT_MAX_TTL;
@ -1110,7 +1089,7 @@ module.exports = function(User) {
if (typeof plain !== 'string') {
return;
}
if ((plain.indexOf('$2a$') === 0 || plain.indexOf('$2b$') === 0) && plain.length === 60) {
if (plain.indexOf('$2a$') === 0 && plain.length === 60) {
// The password is already hashed. It can be the case
// when the instance is loaded from DB
this.$password = plain;
@ -1121,7 +1100,7 @@ module.exports = function(User) {
// Make sure emailVerified is not set by creation
UserModel.beforeRemote('create', function(ctx, user, next) {
const body = ctx.req.body;
var body = ctx.req.body;
if (body && body.emailVerified) {
body.emailVerified = false;
}
@ -1148,7 +1127,7 @@ module.exports = function(User) {
'{{(`include=user`)}}\n\n'),
},
http: {verb: 'post'},
},
}
);
UserModel.remoteMethod(
@ -1157,9 +1136,9 @@ module.exports = function(User) {
description: 'Logout a user with access token.',
accepts: [
{arg: 'access_token', type: 'string', http: function(ctx) {
const req = ctx && ctx.req;
const accessToken = req && req.accessToken;
const tokenID = accessToken ? accessToken.id : undefined;
var req = ctx && ctx.req;
var accessToken = req && req.accessToken;
var tokenID = accessToken ? accessToken.id : undefined;
return tokenID;
}, description: 'Do not supply this argument, it is automatically extracted ' +
@ -1167,7 +1146,7 @@ module.exports = function(User) {
},
],
http: {verb: 'all'},
},
}
);
UserModel.remoteMethod(
@ -1179,7 +1158,7 @@ module.exports = function(User) {
{arg: 'options', type: 'object', http: 'optionsFromRequest'},
],
http: {verb: 'post'},
},
}
);
UserModel.remoteMethod(
@ -1192,7 +1171,7 @@ module.exports = function(User) {
{arg: 'redirect', type: 'string'},
],
http: {verb: 'get', path: '/confirm'},
},
}
);
UserModel.remoteMethod(
@ -1203,7 +1182,7 @@ module.exports = function(User) {
{arg: 'options', type: 'object', required: true, http: {source: 'body'}},
],
http: {verb: 'post', path: '/reset'},
},
}
);
UserModel.remoteMethod(
@ -1217,7 +1196,7 @@ module.exports = function(User) {
{arg: 'options', type: 'object', http: 'optionsFromRequest'},
],
http: {verb: 'POST', path: '/change-password'},
},
}
);
const setPasswordScopes = UserModel.settings.restrictResetPasswordTokenScope ?
@ -1234,7 +1213,7 @@ module.exports = function(User) {
],
accessScopes: setPasswordScopes,
http: {verb: 'POST', path: '/reset-password'},
},
}
);
function getUserIdFromRequestContext(ctx) {
@ -1337,7 +1316,7 @@ module.exports = function(User) {
// This is a programmer's error, use the default status code 500
return next(new Error(
'Invalid use of "options.setPassword". Only "password" can be ' +
'changed when using this option.',
'changed when using this option.'
));
}
@ -1350,7 +1329,7 @@ module.exports = function(User) {
const err = new Error(
'Changing user password via patch/replace API is not allowed. ' +
'Use changePassword() or setPassword() instead.',
'Use changePassword() or setPassword() instead.'
);
err.statusCode = 401;
err.code = 'PASSWORD_CHANGE_NOT_ALLOWED';
@ -1361,8 +1340,8 @@ module.exports = function(User) {
if (ctx.isNewInstance) return next();
if (!ctx.where && !ctx.instance) return next();
const pkName = ctx.Model.definition.idName() || 'id';
let where = ctx.where;
var pkName = ctx.Model.definition.idName() || 'id';
var where = ctx.where;
if (!where) {
where = {};
where[pkName] = ctx.instance[pkName];
@ -1371,22 +1350,15 @@ module.exports = function(User) {
ctx.Model.find({where: where}, ctx.options, function(err, userInstances) {
if (err) return next(err);
ctx.hookState.originalUserData = userInstances.map(function(u) {
const user = {};
var user = {};
user[pkName] = u[pkName];
user.email = u.email;
user.password = u.password;
return user;
});
let emailChanged;
var emailChanged;
if (ctx.instance) {
// Check if map does not return an empty array
// Fix server crashes when try to PUT a non existent id
if (ctx.hookState.originalUserData.length > 0) {
emailChanged = ctx.instance.email !== ctx.hookState.originalUserData[0].email;
} else {
emailChanged = true;
}
emailChanged = ctx.instance.email !== ctx.hookState.originalUserData[0].email;
if (emailChanged && ctx.Model.settings.emailVerificationRequired) {
ctx.instance.emailVerified = false;
}
@ -1407,15 +1379,13 @@ module.exports = function(User) {
if (!ctx.instance && !ctx.data) return next();
if (!ctx.hookState.originalUserData) return next();
const pkName = ctx.Model.definition.idName() || 'id';
const newEmail = (ctx.instance || ctx.data).email;
const newPassword = (ctx.instance || ctx.data).password;
var pkName = ctx.Model.definition.idName() || 'id';
var newEmail = (ctx.instance || ctx.data).email;
var newPassword = (ctx.instance || ctx.data).password;
if (!newEmail && !newPassword) return next();
if (ctx.options.preserveAccessTokens) return next();
const userIdsToExpire = ctx.hookState.originalUserData.filter(function(u) {
var userIdsToExpire = ctx.hookState.originalUserData.filter(function(u) {
return (newEmail && u.email !== newEmail) ||
(newPassword && u.password !== newPassword);
}).map(function(u) {
@ -1426,7 +1396,7 @@ module.exports = function(User) {
};
function emailValidator(err, done) {
const value = this.email;
var value = this.email;
if (value == null)
return;
if (typeof value !== 'string')
@ -1437,9 +1407,9 @@ function emailValidator(err, done) {
}
function joinUrlPath(args) {
let result = arguments[0];
for (let ix = 1; ix < arguments.length; ix++) {
const next = arguments[ix];
var result = arguments[0];
for (var ix = 1; ix < arguments.length; ix++) {
var next = arguments[ix];
result += result[result.length - 1] === '/' && next[0] === '/' ?
next.slice(1) : next;
}

View File

@ -1,14 +1,14 @@
// Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Copyright IBM Corp. 2014,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const g = require('../../lib/globalize');
const loopback = require('../../');
const client = loopback();
const CartItem = require('./models').CartItem;
const remote = loopback.createDataSource({
var g = require('../../lib/globalize');
var loopback = require('../../');
var client = loopback();
var CartItem = require('./models').CartItem;
var remote = loopback.createDataSource({
connector: loopback.Remote,
url: 'http://localhost:3000',
});

View File

@ -1,12 +1,12 @@
// Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Copyright IBM Corp. 2014,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const loopback = require('../../');
var loopback = require('../../');
const CartItem = exports.CartItem = loopback.PersistedModel.extend('CartItem', {
var CartItem = exports.CartItem = loopback.PersistedModel.extend('CartItem', {
tax: {type: Number, default: 0.1},
price: Number,
item: String,
@ -17,7 +17,7 @@ const CartItem = exports.CartItem = loopback.PersistedModel.extend('CartItem', {
CartItem.sum = function(cartId, callback) {
this.find({where: {cartId: cartId}}, function(err, items) {
if (err) return callback(err);
const total = items
var total = items
.map(function(item) {
return item.total();
})
@ -33,7 +33,8 @@ CartItem.remoteMethod('sum',
{
accepts: {arg: 'cartId', type: 'number'},
returns: {arg: 'total', type: 'number'},
});
}
);
CartItem.prototype.total = function() {
return this.price * this.qty * (1 + this.tax);

View File

@ -1,13 +1,13 @@
// Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Copyright IBM Corp. 2014,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const loopback = require('../../');
const server = module.exports = loopback();
const CartItem = require('./models').CartItem;
const memory = loopback.createDataSource({
var loopback = require('../../');
var server = module.exports = loopback();
var CartItem = require('./models').CartItem;
var memory = loopback.createDataSource({
connector: loopback.Memory,
});

View File

@ -1,21 +1,21 @@
// Copyright IBM Corp. 2013,2019. All Rights Reserved.
// Copyright IBM Corp. 2013,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const g = require('../../lib/globalize');
const loopback = require('../../');
const app = loopback();
var g = require('../../lib/globalize');
var loopback = require('../../');
var app = loopback();
app.use(loopback.rest());
const schema = {
var schema = {
name: String,
};
app.dataSource('db', {connector: 'memory'});
const Color = app.registry.createModel('color', schema);
var Color = app.registry.createModel('color', schema);
app.model(Color, {dataSource: 'db'});
Color.create({name: 'red'});

View File

@ -1,23 +1,23 @@
// Copyright IBM Corp. 2013,2019. All Rights Reserved.
// Copyright IBM Corp. 2013,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const g = require('../../lib/globalize');
const models = require('../../lib/models');
const loopback = require('../../');
const app = loopback();
var g = require('../../lib/globalize');
var models = require('../../lib/models');
var loopback = require('../../');
var app = loopback();
app.use(loopback.rest());
const dataSource = loopback.createDataSource('db', {connector: loopback.Memory});
var dataSource = loopback.createDataSource('db', {connector: loopback.Memory});
const Application = models.Application(dataSource);
var Application = models.Application(dataSource);
app.model(Application);
const data = {
var data = {
pushSettings: [{
'platform': 'apns',
'apns': {

View File

@ -1,22 +1,22 @@
// Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Copyright IBM Corp. 2014,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const loopback = require('../../');
const app = loopback();
const db = app.dataSource('db', {connector: 'memory'});
const Color = app.registry.createModel('color', {}, {trackChanges: true});
var loopback = require('../../');
var app = loopback();
var db = app.dataSource('db', {connector: 'memory'});
var Color = app.registry.createModel('color', {}, {trackChanges: true});
app.model(Color, {dataSource: 'db'});
const Color2 = app.registry.createModel('color2', {}, {trackChanges: true});
var Color2 = app.registry.createModel('color2', {}, {trackChanges: true});
app.model(Color2, {dataSource: 'db'});
const target = Color2;
const source = Color;
const SPEED = process.env.SPEED || 100;
let conflicts;
var target = Color2;
var source = Color;
var SPEED = process.env.SPEED || 100;
var conflicts;
const steps = [
var steps = [
createSomeInitialSourceData,
@ -137,7 +137,7 @@ function list(model, msg) {
function run(steps) {
setInterval(function() {
const step = steps.shift();
var step = steps.shift();
if (step) {
console.log(step.name);
step();

View File

@ -1,18 +1,18 @@
// Copyright IBM Corp. 2013,2019. All Rights Reserved.
// Copyright IBM Corp. 2013,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const g = require('../../lib/globalize');
const loopback = require('../../');
const app = loopback();
var g = require('../../lib/globalize');
var loopback = require('../../');
var app = loopback();
app.use(loopback.rest());
const dataSource = app.dataSource('db', {adapter: 'memory'});
var dataSource = app.dataSource('db', {adapter: 'memory'});
const Color = dataSource.define('color', {
var Color = dataSource.define('color', {
'name': String,
});

View File

@ -7,7 +7,7 @@
"0e21aad369dd09e1965c11949303cefd": "Les métadonnées remoting pour {0}.{1} {{\"isStatic\"}} ne correspondent pas au style basé sur le nom de la nouvelle méthode.",
"10e01c895dc0b2fecc385f9f462f1ca6": "une liste de couleurs est disponible sur {{http://localhost:3000/colors}}",
"1b2a6076dccbe91a56f1672eb3b8598c": "Le corps de réponse contient les propriétés de {{AccessToken}} créées lors de la connexion.\nEn fonction de la valeur du paramètre `include`, le corps peut contenir des propriétés supplémentaires :\n\n - `user` - `U+007BUserU+007D` - Données de l'utilisateur connecté. {{(`include=user`)}}\n\n",
"1d7833c3ca2f05fdad8fad7537531c40": "\t OBJET :{0}",
"1d7833c3ca2f05fdad8fad7537531c40": "\t SUJET :{0}",
"1e85f822b547a75d7d385048030e4ecb": "Création de : {0}",
"22fe62fa8d595b72c62208beddaa2a56": "Mettez à jour un élément lié par id pour {0}.",
"275f22ab95671f095640ca99194b7635": "\t DE :{0}",

View File

@ -1,12 +1,12 @@
// Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Copyright IBM Corp. 2014,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const assert = require('assert');
const loopback = require('./loopback');
const debug = require('debug')('loopback:security:access-context');
var assert = require('assert');
var loopback = require('./loopback');
var debug = require('debug')('loopback:security:access-context');
const DEFAULT_SCOPES = ['DEFAULT'];
@ -50,7 +50,7 @@ function AccessContext(context) {
'Application registry is mandatory in AccessContext but missing in provided context');
this.registry = context.registry;
this.principals = context.principals || [];
let model = context.model;
var model = context.model;
model = ('string' === typeof model) ? this.registry.getModel(model) : model;
this.model = model;
this.modelName = model && model.modelName;
@ -77,9 +77,9 @@ function AccessContext(context) {
'AccessToken model must be defined before AccessContext model');
this.accessToken = context.accessToken || loopback.AccessToken.ANONYMOUS;
const principalType = context.principalType || Principal.USER;
const principalId = context.principalId || undefined;
const principalName = context.principalName || undefined;
var principalType = context.principalType || Principal.USER;
var principalId = context.principalId || undefined;
var principalName = context.principalName || undefined;
if (principalId != null) {
this.addPrincipal(principalType, principalId, principalName);
}
@ -126,9 +126,9 @@ AccessContext.permissionOrder = {
* @returns {boolean}
*/
AccessContext.prototype.addPrincipal = function(principalType, principalId, principalName) {
const principal = new Principal(principalType, principalId, principalName);
for (let i = 0; i < this.principals.length; i++) {
const p = this.principals[i];
var principal = new Principal(principalType, principalId, principalName);
for (var i = 0; i < this.principals.length; i++) {
var p = this.principals[i];
if (p.equals(principal)) {
return false;
}
@ -142,7 +142,7 @@ AccessContext.prototype.addPrincipal = function(principalType, principalId, prin
* @returns {*}
*/
AccessContext.prototype.getUserId = function() {
const user = this.getUser();
var user = this.getUser();
return user && user.id;
};
@ -151,10 +151,10 @@ AccessContext.prototype.getUserId = function() {
* @returns {*}
*/
AccessContext.prototype.getUser = function() {
const BaseUser = this.registry.getModel('User');
for (let i = 0; i < this.principals.length; i++) {
const p = this.principals[i];
const isBuiltinPrincipal = p.type === Principal.APP ||
var BaseUser = this.registry.getModel('User');
for (var i = 0; i < this.principals.length; i++) {
var p = this.principals[i];
var isBuiltinPrincipal = p.type === Principal.APP ||
p.type === Principal.ROLE ||
p.type == Principal.SCOPE;
if (isBuiltinPrincipal) continue;
@ -165,7 +165,7 @@ AccessContext.prototype.getUser = function() {
}
// or permit to resolve a valid user model
const userModel = this.registry.findModel(p.type);
var userModel = this.registry.findModel(p.type);
if (!userModel) continue;
if (userModel.prototype instanceof BaseUser) {
return {id: p.id, principalType: p.type};
@ -178,8 +178,8 @@ AccessContext.prototype.getUser = function() {
* @returns {*}
*/
AccessContext.prototype.getAppId = function() {
for (let i = 0; i < this.principals.length; i++) {
const p = this.principals[i];
for (var i = 0; i < this.principals.length; i++) {
var p = this.principals[i];
if (p.type === Principal.APPLICATION) {
return p.id;
}
@ -325,7 +325,7 @@ function AccessRequest(model, property, accessType, permission, methodNames, reg
}
if (arguments.length === 1 && typeof model === 'object') {
// The argument is an object that contains all required properties
const obj = model || {};
var obj = model || {};
this.model = obj.model || AccessContext.ALL;
this.property = obj.property || AccessContext.ALL;
this.accessType = obj.accessType || AccessContext.ALL;
@ -363,10 +363,10 @@ AccessRequest.prototype.isWildcard = function() {
*/
AccessRequest.prototype.exactlyMatches = function(acl) {
const matchesModel = acl.model === this.model;
const matchesProperty = acl.property === this.property;
const matchesMethodName = this.methodNames.indexOf(acl.property) !== -1;
const matchesAccessType = acl.accessType === this.accessType;
var matchesModel = acl.model === this.model;
var matchesProperty = acl.property === this.property;
var matchesMethodName = this.methodNames.indexOf(acl.property) !== -1;
var matchesAccessType = acl.accessType === this.accessType;
if (matchesModel && matchesAccessType) {
return matchesProperty || matchesMethodName;
@ -388,9 +388,9 @@ AccessRequest.prototype.settleDefaultPermission = function(defaultPermission) {
if (this.permission !== 'DEFAULT')
return;
const modelName = this.model;
var modelName = this.model;
if (!defaultPermission) {
const modelClass = this.registry.findModel(modelName);
var modelClass = this.registry.findModel(modelName);
defaultPermission = modelClass && modelClass.settings.defaultPermission;
}

View File

@ -1,4 +1,4 @@
// Copyright IBM Corp. 2013,2019. All Rights Reserved.
// Copyright IBM Corp. 2013,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
@ -8,17 +8,17 @@
*/
'use strict';
const g = require('./globalize');
const DataSource = require('loopback-datasource-juggler').DataSource;
const Registry = require('./registry');
const assert = require('assert');
const fs = require('fs');
const extend = require('util')._extend;
const RemoteObjects = require('strong-remoting');
const classify = require('underscore.string/classify');
const camelize = require('underscore.string/camelize');
const path = require('path');
const util = require('util');
var g = require('./globalize');
var DataSource = require('loopback-datasource-juggler').DataSource;
var Registry = require('./registry');
var assert = require('assert');
var fs = require('fs');
var extend = require('util')._extend;
var RemoteObjects = require('strong-remoting');
var classify = require('underscore.string/classify');
var camelize = require('underscore.string/camelize');
var path = require('path');
var util = require('util');
/**
* The `App` object represents a Loopback application.
@ -49,7 +49,7 @@ function App() {
* Export the app prototype.
*/
const app = module.exports = {};
var app = module.exports = {};
/**
* Lazily load a set of [remote objects](http://apidocs.strongloop.com/strong-remoting/#remoteobjectsoptions).
@ -62,7 +62,7 @@ app.remotes = function() {
if (this._remotes) {
return this._remotes;
} else {
let options = {};
var options = {};
if (this.get) {
options = this.get('remoting');
@ -78,7 +78,7 @@ app.remotes = function() {
app.disuse = function(route) {
if (this.stack) {
for (let i = 0; i < this.stack.length; i++) {
for (var i = 0; i < this.stack.length; i++) {
if (this.stack[i].route === route) {
this.stack.splice(i, 1);
}
@ -111,11 +111,11 @@ app.disuse = function(route) {
*/
app.model = function(Model, config) {
let isPublic = true;
const registry = this.registry;
var isPublic = true;
var registry = this.registry;
if (typeof Model === 'string') {
const msg = 'app.model(modelName, settings) is no longer supported. ' +
var msg = 'app.model(modelName, settings) is no longer supported. ' +
'Use app.registry.createModel(modelName, definition) and ' +
'app.model(ModelCtor, config) instead.';
throw new Error(msg);
@ -130,7 +130,7 @@ app.model = function(Model, config) {
Model.modelName + ' must be a descendant of loopback.Model');
}
const modelName = Model.modelName;
var modelName = Model.modelName;
this.models[modelName] =
this.models[classify(modelName)] =
this.models[camelize(modelName)] = Model;
@ -149,13 +149,11 @@ app.model = function(Model, config) {
this.emit('modelRemoted', Model.sharedClass);
}
const self = this;
var self = this;
Model.on('remoteMethodDisabled', function(model, methodName) {
clearHandlerCache(self);
self.emit('remoteMethodDisabled', model, methodName);
});
Model.on('remoteMethodAdded', function(model) {
clearHandlerCache(self);
self.emit('remoteMethodAdded', model);
});
@ -266,7 +264,7 @@ app.models = function() {
*/
app.dataSource = function(name, config) {
try {
const ds = dataSourcesFromConfig(name, config, this.connectors, this.registry);
var ds = dataSourcesFromConfig(name, config, this.connectors, this.registry);
this.dataSources[name] =
this.dataSources[classify(name)] =
this.dataSources[camelize(name)] = ds;
@ -307,7 +305,7 @@ app.connector = function(name, connector) {
*/
app.remoteObjects = function() {
const result = {};
var result = {};
this.remotes().classes().forEach(function(sharedClass) {
result[sharedClass.name] = sharedClass.ctor;
@ -322,13 +320,13 @@ app.remoteObjects = function() {
*/
app.handler = function(type, options) {
const handlers = this._handlers || (this._handlers = {});
var handlers = this._handlers || (this._handlers = {});
if (handlers[type]) {
return handlers[type];
}
const remotes = this.remotes();
const handler = this._handlers[type] = remotes.handler(type, options);
var remotes = this.remotes();
var handler = this._handlers[type] = remotes.handler(type, options);
remotes.classes().forEach(function(sharedClass) {
sharedClass.ctor.emit('mounted', app, sharedClass, remotes);
@ -348,18 +346,18 @@ app.dataSources = app.datasources = {};
*/
app.enableAuth = function(options) {
const AUTH_MODELS = ['User', 'AccessToken', 'ACL', 'Role', 'RoleMapping'];
var AUTH_MODELS = ['User', 'AccessToken', 'ACL', 'Role', 'RoleMapping'];
const remotes = this.remotes();
const app = this;
var remotes = this.remotes();
var app = this;
if (options && options.dataSource) {
const appModels = app.registry.modelBuilder.models;
var appModels = app.registry.modelBuilder.models;
AUTH_MODELS.forEach(function(m) {
const Model = app.registry.findModel(m);
var Model = app.registry.findModel(m);
if (!Model) {
throw new Error(
g.f('Authentication requires model %s to be defined.', m),
g.f('Authentication requires model %s to be defined.', m)
);
}
@ -367,10 +365,10 @@ app.enableAuth = function(options) {
// Find descendants of Model that are attached,
// for example "Customer" extending "User" model
for (const name in appModels) {
const candidate = appModels[name];
const isSubclass = candidate.prototype instanceof Model;
const isAttached = !!candidate.dataSource || !!candidate.app;
for (var name in appModels) {
var candidate = appModels[name];
var isSubclass = candidate.prototype instanceof Model;
var isAttached = !!candidate.dataSource || !!candidate.app;
if (isSubclass && isAttached) return;
}
@ -382,22 +380,22 @@ app.enableAuth = function(options) {
}
remotes.authorization = function(ctx, next) {
const method = ctx.method;
const req = ctx.req;
const Model = method.ctor;
const modelInstance = ctx.instance;
var method = ctx.method;
var req = ctx.req;
var Model = method.ctor;
var modelInstance = ctx.instance;
const modelId = modelInstance && modelInstance.id ||
var modelId = modelInstance && modelInstance.id ||
// replacement for deprecated req.param()
(req.params && req.params.id !== undefined ? req.params.id :
req.body && req.body.id !== undefined ? req.body.id :
req.query && req.query.id !== undefined ? req.query.id :
undefined);
const modelName = Model.modelName;
var modelName = Model.modelName;
const modelSettings = Model.settings || {};
let errStatusCode = modelSettings.aclErrorStatus || app.get('aclErrorStatus') || 401;
var modelSettings = Model.settings || {};
var errStatusCode = modelSettings.aclErrorStatus || app.get('aclErrorStatus') || 401;
if (!req.accessToken) {
errStatusCode = 401;
}
@ -415,7 +413,7 @@ app.enableAuth = function(options) {
} else if (allowed) {
next();
} else {
const messages = {
var messages = {
403: {
message: g.f('Access Denied'),
code: 'ACCESS_DENIED',
@ -430,12 +428,12 @@ app.enableAuth = function(options) {
},
};
const e = new Error(messages[errStatusCode].message || messages[403].message);
var e = new Error(messages[errStatusCode].message || messages[403].message);
e.statusCode = errStatusCode;
e.code = messages[errStatusCode].code || messages[403].code;
next(e);
}
},
}
);
} else {
next();
@ -486,7 +484,7 @@ app._verifyAuthModelRelations = function() {
'custom User subclass, but does not fix AccessToken relations ' +
'to use this new model.\n' +
'Learn more at http://ibm.biz/setup-loopback-auth',
Model.modelName, userName, userName,
Model.modelName, userName, userName
);
return;
}
@ -495,7 +493,7 @@ app._verifyAuthModelRelations = function() {
'The model %j does not have "belongsTo User-like model" relation ' +
'configured.\n' +
'Learn more at http://ibm.biz/setup-loopback-auth',
Model.modelName,
Model.modelName
);
}
@ -509,7 +507,7 @@ app._verifyAuthModelRelations = function() {
'The app configuration follows the multiple user models setup ' +
'as described in http://ibm.biz/setup-loopback-auth',
'The built-in role resolver $owner is not currently compatible ' +
'with this configuration and should not be used in production.',
'with this configuration and should not be used in production.'
);
}
return;
@ -526,7 +524,7 @@ app._verifyAuthModelRelations = function() {
'AccessToken subclass, but does not fix User relations to use this ' +
'new model.\n' +
'Learn more at http://ibm.biz/setup-loopback-auth',
Model.modelName, accessTokenName, accessTokenName,
Model.modelName, accessTokenName, accessTokenName
);
return;
}
@ -535,19 +533,19 @@ app._verifyAuthModelRelations = function() {
'The model %j does not have "hasMany AccessToken-like models" relation ' +
'configured.\n' +
'Learn more at http://ibm.biz/setup-loopback-auth',
Model.modelName,
Model.modelName
);
}
};
app.boot = function(options) {
throw new Error(
g.f('{{`app.boot`}} was removed, use the new module {{loopback-boot}} instead'),
g.f('{{`app.boot`}} was removed, use the new module {{loopback-boot}} instead')
);
};
function dataSourcesFromConfig(name, config, connectorRegistry, registry) {
let connectorPath;
var connectorPath;
assert(typeof config === 'object',
'can not create data source without config object');
@ -574,7 +572,7 @@ function configureModel(ModelCtor, config, app) {
assert(ModelCtor.prototype instanceof ModelCtor.registry.getModel('Model'),
ModelCtor.modelName + ' must be a descendant of loopback.Model');
let dataSource = config.dataSource;
var dataSource = config.dataSource;
if (dataSource) {
if (typeof dataSource === 'string') {
@ -584,7 +582,7 @@ function configureModel(ModelCtor, config, app) {
assert(
dataSource instanceof DataSource,
ModelCtor.modelName + ' is referencing a dataSource that does not exist: "' +
config.dataSource + '"',
config.dataSource + '"'
);
}
@ -627,15 +625,15 @@ function clearHandlerCache(app) {
* as the request handler.
*/
app.listen = function(cb) {
const self = this;
var self = this;
const server = require('http').createServer(this);
var server = require('http').createServer(this);
server.on('listening', function() {
self.set('port', this.address().port);
let listeningOnAll = false;
let host = self.get('host');
var listeningOnAll = false;
var host = self.get('host');
if (!host) {
listeningOnAll = true;
host = this.address().address;
@ -650,17 +648,17 @@ app.listen = function(cb) {
// that can be copied and pasted into the browser.
host = 'localhost';
}
const url = 'http://' + host + ':' + self.get('port') + '/';
var url = 'http://' + host + ':' + self.get('port') + '/';
self.set('url', url);
}
});
const useAppConfig =
var useAppConfig =
arguments.length === 0 ||
(arguments.length == 1 && typeof arguments[0] == 'function');
if (useAppConfig) {
let port = this.get('port');
var port = this.get('port');
// NOTE(bajtos) port:undefined no longer works on node@6,
// we must pass port:0 explicitly
if (port === undefined) port = 0;

View File

@ -1,11 +1,11 @@
// Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Copyright IBM Corp. 2014,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const EventEmitter = require('events').EventEmitter;
const util = require('util');
var EventEmitter = require('events').EventEmitter;
var util = require('util');
module.exports = browserExpress;

View File

@ -1,4 +1,4 @@
// Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Copyright IBM Corp. 2014,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
@ -12,57 +12,57 @@ module.exports = function(registry) {
registry.KeyValueModel = createModel(
require('../common/models/key-value-model.json'),
require('../common/models/key-value-model.js'),
require('../common/models/key-value-model.js')
);
registry.Email = createModel(
require('../common/models/email.json'),
require('../common/models/email.js'),
require('../common/models/email.js')
);
registry.Application = createModel(
require('../common/models/application.json'),
require('../common/models/application.js'),
require('../common/models/application.js')
);
registry.AccessToken = createModel(
require('../common/models/access-token.json'),
require('../common/models/access-token.js'),
require('../common/models/access-token.js')
);
registry.User = createModel(
require('../common/models/user.json'),
require('../common/models/user.js'),
require('../common/models/user.js')
);
registry.RoleMapping = createModel(
require('../common/models/role-mapping.json'),
require('../common/models/role-mapping.js'),
require('../common/models/role-mapping.js')
);
registry.Role = createModel(
require('../common/models/role.json'),
require('../common/models/role.js'),
require('../common/models/role.js')
);
registry.ACL = createModel(
require('../common/models/acl.json'),
require('../common/models/acl.js'),
require('../common/models/acl.js')
);
registry.Scope = createModel(
require('../common/models/scope.json'),
require('../common/models/scope.js'),
require('../common/models/scope.js')
);
registry.Change = createModel(
require('../common/models/change.json'),
require('../common/models/change.js'),
require('../common/models/change.js')
);
registry.Checkpoint = createModel(
require('../common/models/checkpoint.json'),
require('../common/models/checkpoint.js'),
require('../common/models/checkpoint.js')
);
function createModel(definitionJson, customizeFn) {
@ -74,7 +74,7 @@ module.exports = function(registry) {
// object instance it loaded during the first call.
definitionJson = cloneDeepJson(definitionJson);
const Model = registry.createModel(definitionJson);
var Model = registry.createModel(definitionJson);
customizeFn(Model);
return Model;
}

View File

@ -1,19 +1,19 @@
// Copyright IBM Corp. 2017,2019. All Rights Reserved.
// Copyright IBM Corp. 2017,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const util = require('util');
const extend = require('util')._extend;
const g = require('./globalize');
var util = require('util');
var extend = require('util')._extend;
var g = require('./globalize');
module.exports = function(modelCtor, remotingConfig, modelConfig) {
const settings = {};
var settings = {};
// apply config.json settings
const configHasSharedMethodsSettings = remotingConfig &&
var configHasSharedMethodsSettings = remotingConfig &&
remotingConfig.sharedMethods &&
typeof remotingConfig.sharedMethods === 'object';
if (configHasSharedMethodsSettings)
@ -21,7 +21,7 @@ module.exports = function(modelCtor, remotingConfig, modelConfig) {
// apply model-config.json settings
const options = modelConfig.options;
const modelConfigHasSharedMethodsSettings = options &&
var modelConfigHasSharedMethodsSettings = options &&
options.remoting &&
options.remoting.sharedMethods &&
typeof options.remoting.sharedMethods === 'object';
@ -30,30 +30,30 @@ module.exports = function(modelCtor, remotingConfig, modelConfig) {
// validate setting values
Object.keys(settings).forEach(function(setting) {
const settingValue = settings[setting];
const settingValueType = typeof settingValue;
var settingValue = settings[setting];
var settingValueType = typeof settingValue;
if (settingValueType !== 'boolean')
throw new TypeError(g.f('Expected boolean, got %s', settingValueType));
});
// set sharedMethod.shared using the merged settings
const sharedMethods = modelCtor.sharedClass.methods({includeDisabled: true});
var sharedMethods = modelCtor.sharedClass.methods({includeDisabled: true});
// re-map glob style values to regular expressions
const tests = Object
var tests = Object
.keys(settings)
.filter(function(setting) {
return settings.hasOwnProperty(setting) && setting.indexOf('*') >= 0;
})
.map(function(setting) {
// Turn * into an testable regexp string
const glob = escapeRegExp(setting).replace(/\*/g, '(.)*');
var glob = escapeRegExp(setting).replace(/\*/g, '(.)*');
return {regex: new RegExp(glob), setting: settings[setting]};
}) || [];
sharedMethods.forEach(function(sharedMethod) {
// use the specific setting if it exists
const methodName = sharedMethod.isStatic ? sharedMethod.name : 'prototype.' + sharedMethod.name;
const hasSpecificSetting = settings.hasOwnProperty(methodName);
var methodName = sharedMethod.isStatic ? sharedMethod.name : 'prototype.' + sharedMethod.name;
var hasSpecificSetting = settings.hasOwnProperty(methodName);
if (hasSpecificSetting) {
if (settings[methodName] === false) {
sharedMethod.sharedClass.disableMethodByName(methodName);

View File

@ -1,4 +1,4 @@
// Copyright IBM Corp. 2013,2019. All Rights Reserved.
// Copyright IBM Corp. 2013,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
@ -14,11 +14,11 @@ module.exports = Connector;
* Module dependencies.
*/
const EventEmitter = require('events').EventEmitter;
const debug = require('debug')('connector');
const util = require('util');
const inherits = util.inherits;
const assert = require('assert');
var EventEmitter = require('events').EventEmitter;
var debug = require('debug')('connector');
var util = require('util');
var inherits = util.inherits;
var assert = require('assert');
/**
* Create a new `Connector` with the given `options`.
@ -45,7 +45,7 @@ inherits(Connector, EventEmitter);
*/
Connector._createJDBAdapter = function(jdbModule) {
const fauxSchema = {};
var fauxSchema = {};
jdbModule.initialize(fauxSchema, function() {
// connected
});

View File

@ -1,4 +1,4 @@
// Copyright IBM Corp. 2013,2019. All Rights Reserved.
// Copyright IBM Corp. 2013,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
@ -8,11 +8,11 @@
*/
'use strict';
const g = require('../globalize');
const mailer = require('nodemailer');
const assert = require('assert');
const debug = require('debug')('loopback:connector:mail');
const loopback = require('../loopback');
var g = require('../globalize');
var mailer = require('nodemailer');
var assert = require('assert');
var debug = require('debug')('loopback:connector:mail');
var loopback = require('../loopback');
/**
* Export the MailConnector class.
@ -27,7 +27,7 @@ module.exports = MailConnector;
function MailConnector(settings) {
assert(typeof settings === 'object', 'cannot initialize MailConnector without a settings object');
let transports = settings.transports;
var transports = settings.transports;
// if transports is not in settings object AND settings.transport exists
if (!transports && settings.transport) {
@ -74,17 +74,17 @@ MailConnector.prototype.DataAccessObject = Mailer;
*/
MailConnector.prototype.setupTransport = function(setting) {
const connector = this;
var connector = this;
connector.transports = connector.transports || [];
connector.transportsIndex = connector.transportsIndex || {};
let transport;
const transportType = (setting.type || 'STUB').toLowerCase();
var transport;
var transportType = (setting.type || 'STUB').toLowerCase();
if (transportType === 'smtp') {
transport = mailer.createTransport(setting);
} else {
const transportModuleName = 'nodemailer-' + transportType + '-transport';
const transportModule = require(transportModuleName);
var transportModuleName = 'nodemailer-' + transportType + '-transport';
var transportModule = require(transportModuleName);
transport = mailer.createTransport(transportModule(setting));
}
@ -138,12 +138,12 @@ MailConnector.prototype.defaultTransport = function() {
*/
Mailer.send = function(options, fn) {
const dataSource = this.dataSource;
const settings = dataSource && dataSource.settings;
const connector = dataSource.connector;
var dataSource = this.dataSource;
var settings = dataSource && dataSource.settings;
var connector = dataSource.connector;
assert(connector, 'Cannot send mail without a connector!');
let transport = connector.transportForName(options.transport);
var transport = connector.transportForName(options.transport);
if (!transport) {
transport = connector.defaultTransport();

View File

@ -1,4 +1,4 @@
// Copyright IBM Corp. 2013,2019. All Rights Reserved.
// Copyright IBM Corp. 2013,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
@ -14,12 +14,12 @@ module.exports = Memory;
* Module dependencies.
*/
const Connector = require('./base-connector');
const debug = require('debug')('memory');
const util = require('util');
const inherits = util.inherits;
const assert = require('assert');
const JdbMemory = require('loopback-datasource-juggler/lib/connectors/memory');
var Connector = require('./base-connector');
var debug = require('debug')('memory');
var util = require('util');
var inherits = util.inherits;
var assert = require('assert');
var JdbMemory = require('loopback-datasource-juggler/lib/connectors/memory');
/**
* Create a new `Memory` connector with the given `options`.

View File

@ -1,12 +1,12 @@
// Copyright IBM Corp. 2016,2019. All Rights Reserved.
// Copyright IBM Corp. 2016,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const g = require('./globalize');
const juggler = require('loopback-datasource-juggler');
const remoting = require('strong-remoting');
var g = require('./globalize');
var juggler = require('loopback-datasource-juggler');
var remoting = require('strong-remoting');
module.exports = function(loopback) {
juggler.getCurrentContext =
@ -15,7 +15,7 @@ module.exports = function(loopback) {
throw new Error(g.f(
'%s was removed in version 3.0. See %s for more details.',
'loopback.getCurrentContext()',
'http://loopback.io/doc/en/lb2/Using-current-context.html',
'http://loopback.io/doc/en/lb2/Using-current-context.html'
));
};
@ -23,7 +23,7 @@ module.exports = function(loopback) {
throw new Error(g.f(
'%s was removed in version 3.0. See %s for more details.',
'loopback.runInContext()',
'http://loopback.io/doc/en/lb2/Using-current-context.html',
'http://loopback.io/doc/en/lb2/Using-current-context.html'
));
};
@ -31,7 +31,7 @@ module.exports = function(loopback) {
throw new Error(g.f(
'%s was removed in version 3.0. See %s for more details.',
'loopback.createContext()',
'http://loopback.io/doc/en/lb2/Using-current-context.html',
'http://loopback.io/doc/en/lb2/Using-current-context.html'
));
};
};

View File

@ -1,11 +1,11 @@
// Copyright IBM Corp. 2016,2019. All Rights Reserved.
// Copyright IBM Corp. 2016,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const path = require('path');
const SG = require('strong-globalize');
var path = require('path');
var SG = require('strong-globalize');
SG.SetRootDir(path.join(__dirname, '..'), {autonomousMsgLoading: 'all'});
module.exports = SG();

View File

@ -1,4 +1,4 @@
// Copyright IBM Corp. 2013,2019. All Rights Reserved.
// Copyright IBM Corp. 2013,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
@ -8,17 +8,17 @@
*/
'use strict';
const express = require('express');
const loopbackExpress = require('./server-app');
const proto = require('./application');
const fs = require('fs');
const ejs = require('ejs');
const path = require('path');
const merge = require('util')._extend;
const assert = require('assert');
const Registry = require('./registry');
const juggler = require('loopback-datasource-juggler');
const configureSharedMethods = require('./configure-shared-methods');
var express = require('express');
var loopbackExpress = require('./server-app');
var proto = require('./application');
var fs = require('fs');
var ejs = require('ejs');
var path = require('path');
var merge = require('util')._extend;
var assert = require('assert');
var Registry = require('./registry');
var juggler = require('loopback-datasource-juggler');
var configureSharedMethods = require('./configure-shared-methods');
/**
* LoopBack core module. It provides static properties and
@ -40,7 +40,7 @@ const configureSharedMethods = require('./configure-shared-methods');
* @header loopback
*/
const loopback = module.exports = createApplication;
var loopback = module.exports = createApplication;
/*!
* Framework version.
@ -73,7 +73,7 @@ Object.defineProperties(loopback, {
*/
function createApplication(options) {
const app = loopbackExpress();
var app = loopbackExpress();
merge(app, proto);
@ -107,7 +107,7 @@ function createApplication(options) {
if (loopback.localRegistry || options && options.localRegistry === true) {
// setup the app registry
const registry = app.registry = new Registry();
var registry = app.registry = new Registry();
if (options && options.loadBuiltinModels === true) {
require('./builtin-models')(registry);
}
@ -119,8 +119,8 @@ function createApplication(options) {
}
function mixin(source) {
for (const key in source) {
const desc = Object.getOwnPropertyDescriptor(source, key);
for (var key in source) {
var desc = Object.getOwnPropertyDescriptor(source, key);
// Fix for legacy (pre-ES5) browsers like PhantomJS
if (!desc) continue;
@ -204,8 +204,8 @@ loopback.remoteMethod = function(fn, options) {
*/
loopback.template = function(file) {
const templates = this._templates || (this._templates = {});
const str = templates[file] || (templates[file] = fs.readFileSync(file, 'utf8'));
var templates = this._templates || (this._templates = {});
var str = templates[file] || (templates[file] = fs.readFileSync(file, 'utf8'));
return ejs.compile(str, {
filename: file,
});

View File

@ -1,4 +1,4 @@
// Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Copyright IBM Corp. 2014,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
@ -7,14 +7,14 @@
* Module Dependencies.
*/
'use strict';
const g = require('./globalize');
const assert = require('assert');
const debug = require('debug')('loopback:model');
const RemoteObjects = require('strong-remoting');
const SharedClass = require('strong-remoting').SharedClass;
const extend = require('util')._extend;
var g = require('./globalize');
var assert = require('assert');
var debug = require('debug')('loopback:model');
var RemoteObjects = require('strong-remoting');
var SharedClass = require('strong-remoting').SharedClass;
var extend = require('util')._extend;
const deprecated = require('depd')('loopback');
var deprecated = require('depd')('loopback');
module.exports = function(registry) {
/**
@ -104,7 +104,7 @@ module.exports = function(registry) {
* @property {Array.<Object>} settings.acls Array of ACLs for the model.
* @class
*/
const Model = registry.modelBuilder.define('Model');
var Model = registry.modelBuilder.define('Model');
Model.registry = registry;
@ -115,23 +115,23 @@ module.exports = function(registry) {
*/
Model.setup = function() {
const ModelCtor = this;
const Parent = this.super_;
var ModelCtor = this;
var Parent = this.super_;
if (!ModelCtor.registry && Parent && Parent.registry) {
ModelCtor.registry = Parent.registry;
}
const options = this.settings;
const typeName = this.modelName;
var options = this.settings;
var typeName = this.modelName;
// support remoting prototype methods
// it's important to setup this function *before* calling `new SharedClass`
// otherwise remoting metadata from our base model is picked up
ModelCtor.sharedCtor = function(data, id, options, fn) {
const ModelCtor = this;
var ModelCtor = this;
const isRemoteInvocationWithOptions = typeof data !== 'object' &&
var isRemoteInvocationWithOptions = typeof data !== 'object' &&
typeof id === 'object' &&
typeof options === 'function';
if (isRemoteInvocationWithOptions) {
@ -161,13 +161,13 @@ module.exports = function(registry) {
}
if (id != null && data) {
const model = new ModelCtor(data);
var model = new ModelCtor(data);
model.id = id;
fn(null, model);
} else if (data) {
fn(null, new ModelCtor(data));
} else if (id != null) {
const filter = {};
var filter = {};
ModelCtor.findById(id, filter, options, function(err, model) {
if (err) {
fn(err);
@ -185,7 +185,7 @@ module.exports = function(registry) {
}
};
const idDesc = ModelCtor.modelName + ' id';
var idDesc = ModelCtor.modelName + ' id';
ModelCtor.sharedCtor.accepts = [
{arg: 'id', type: 'any', required: true, http: {source: 'path'},
description: idDesc},
@ -199,21 +199,21 @@ module.exports = function(registry) {
ModelCtor.sharedCtor.returns = {root: true};
const remotingOptions = {};
var remotingOptions = {};
extend(remotingOptions, options.remoting || {});
// create a sharedClass
const sharedClass = ModelCtor.sharedClass = new SharedClass(
var sharedClass = ModelCtor.sharedClass = new SharedClass(
ModelCtor.modelName,
ModelCtor,
remotingOptions,
remotingOptions
);
// before remote hook
ModelCtor.beforeRemote = function(name, fn) {
const className = this.modelName;
var className = this.modelName;
this._runWhenAttachedToApp(function(app) {
const remotes = app.remotes();
var remotes = app.remotes();
remotes.before(className + '.' + name, function(ctx, next) {
return fn(ctx, ctx.result, next);
});
@ -222,9 +222,9 @@ module.exports = function(registry) {
// after remote hook
ModelCtor.afterRemote = function(name, fn) {
const className = this.modelName;
var className = this.modelName;
this._runWhenAttachedToApp(function(app) {
const remotes = app.remotes();
var remotes = app.remotes();
remotes.after(className + '.' + name, function(ctx, next) {
return fn(ctx, ctx.result, next);
});
@ -232,16 +232,16 @@ module.exports = function(registry) {
};
ModelCtor.afterRemoteError = function(name, fn) {
const className = this.modelName;
var className = this.modelName;
this._runWhenAttachedToApp(function(app) {
const remotes = app.remotes();
var remotes = app.remotes();
remotes.afterError(className + '.' + name, fn);
});
};
ModelCtor._runWhenAttachedToApp = function(fn) {
if (this.app) return fn(this.app);
const self = this;
var self = this;
self.once('attached', function() {
fn(self.app);
});
@ -250,19 +250,19 @@ module.exports = function(registry) {
if ('injectOptionsFromRemoteContext' in options) {
console.warn(g.f(
'%s is using model setting %s which is no longer available.',
typeName, 'injectOptionsFromRemoteContext',
typeName, 'injectOptionsFromRemoteContext'
));
console.warn(g.f(
'Please rework your app to use the offical solution for injecting ' +
'"options" argument from request context,\nsee %s',
'http://loopback.io/doc/en/lb3/Using-current-context.html',
'http://loopback.io/doc/en/lb3/Using-current-context.html'
));
}
// resolve relation functions
sharedClass.resolve(function resolver(define) {
const relations = ModelCtor.relations || {};
const defineRaw = define;
var relations = ModelCtor.relations || {};
var defineRaw = define;
define = function(name, options, fn) {
if (options.accepts) {
options = extend({}, options);
@ -272,8 +272,8 @@ module.exports = function(registry) {
};
// get the relations
for (const relationName in relations) {
const relation = relations[relationName];
for (var relationName in relations) {
var relation = relations[relationName];
if (relation.type === 'belongsTo') {
ModelCtor.belongsToRemoting(relationName, relation, define);
} else if (
@ -295,8 +295,8 @@ module.exports = function(registry) {
}
// handle scopes
const scopes = ModelCtor.scopes || {};
for (const scopeName in scopes) {
var scopes = ModelCtor.scopes || {};
for (var scopeName in scopes) {
ModelCtor.scopeRemoting(scopeName, scopes[scopeName], define);
}
});
@ -307,9 +307,9 @@ module.exports = function(registry) {
/*!
* Get the reference to ACL in a lazy fashion to avoid race condition in require
*/
let _aclModel = null;
var _aclModel = null;
Model._ACL = function getACL(ACL) {
const registry = this.registry;
var registry = this.registry;
if (ACL !== undefined) {
// The function is used as a setter
_aclModel = ACL;
@ -317,7 +317,7 @@ module.exports = function(registry) {
if (_aclModel) {
return _aclModel;
}
const aclModel = registry.getModel('ACL');
var aclModel = registry.getModel('ACL');
_aclModel = registry.getModelByType(aclModel);
return _aclModel;
};
@ -335,9 +335,9 @@ module.exports = function(registry) {
*/
Model.checkAccess = function(token, modelId, sharedMethod, ctx, callback) {
const ANONYMOUS = registry.getModel('AccessToken').ANONYMOUS;
var ANONYMOUS = registry.getModel('AccessToken').ANONYMOUS;
token = token || ANONYMOUS;
const aclModel = Model._ACL();
var aclModel = Model._ACL();
ctx = ctx || {};
if (typeof ctx === 'function' && callback === undefined) {
@ -373,10 +373,10 @@ module.exports = function(registry) {
}
assert(
typeof method === 'object',
'method is a required argument and must be a RemoteMethod object',
'method is a required argument and must be a RemoteMethod object'
);
const ACL = Model._ACL();
var ACL = Model._ACL();
// Check the explicit setting of accessType
if (method.accessType) {
@ -390,7 +390,7 @@ module.exports = function(registry) {
}
// Default GET requests to READ
let verb = method.http && method.http.verb;
var verb = method.http && method.http.verb;
if (typeof verb === 'string') {
verb = verb.toUpperCase();
}
@ -438,7 +438,7 @@ module.exports = function(registry) {
*/
Model.getApp = function(callback) {
const self = this;
var self = this;
self._runWhenAttachedToApp(function(app) {
assert(self.app);
assert.equal(app, self.app);
@ -463,21 +463,21 @@ module.exports = function(registry) {
Model.remoteMethod = function(name, options) {
if (options.isStatic === undefined) {
const m = name.match(/^prototype\.(.*)$/);
var m = name.match(/^prototype\.(.*)$/);
options.isStatic = !m;
name = options.isStatic ? name : m[1];
}
if (options.accepts) {
options = extend({}, options);
options.accepts = setupOptionsArgs(options.accepts, this);
options.accepts = setupOptionsArgs(options.accepts);
}
this.sharedClass.defineMethod(name, options);
this.emit('remoteMethodAdded', this.sharedClass);
};
function setupOptionsArgs(accepts, modelClass) {
function setupOptionsArgs(accepts) {
if (!Array.isArray(accepts))
accepts = [accepts];
@ -485,33 +485,21 @@ module.exports = function(registry) {
if (arg.http && arg.http === 'optionsFromRequest') {
// clone to preserve the input value
arg = extend({}, arg);
arg.http = createOptionsViaModelMethod.bind(modelClass);
arg.http = createOptionsViaModelMethod;
}
return arg;
});
}
function createOptionsViaModelMethod(ctx) {
const ModelCtor = (ctx.method && ctx.method.ctor) || this;
/**
* Configure default values for juggler settings to protect user-supplied
* input from attacking juggler
*/
const DEFAULT_OPTIONS = {
// Default to `true` so that hidden properties cannot be used in query
prohibitHiddenPropertiesInQuery: ModelCtor._getProhibitHiddenPropertiesInQuery({}, true),
// Default to `12` for the max depth of a query object
maxDepthOfQuery: ModelCtor._getMaxDepthOfQuery({}, 12),
// Default to `32` for the max depth of a data object
maxDepthOfData: ModelCtor._getMaxDepthOfData({}, 32),
};
var EMPTY_OPTIONS = {};
var ModelCtor = ctx.method && ctx.method.ctor;
if (!ModelCtor)
return EMPTY_OPTIONS;
if (typeof ModelCtor.createOptionsFromRemotingContext !== 'function')
return DEFAULT_OPTIONS;
return EMPTY_OPTIONS;
debug('createOptionsFromRemotingContext for %s', ctx.method.stringName);
return Object.assign(DEFAULT_OPTIONS,
ModelCtor.createOptionsFromRemotingContext(ctx));
return ModelCtor.createOptionsFromRemotingContext(ctx);
}
/**
@ -526,7 +514,7 @@ module.exports = function(registry) {
Model.disableRemoteMethod = function(name, isStatic) {
deprecated('Model.disableRemoteMethod is deprecated. ' +
'Use Model.disableRemoteMethodByName instead.');
const key = this.sharedClass.getKeyFromMethodNameAndTarget(name, isStatic);
var key = this.sharedClass.getKeyFromMethodNameAndTarget(name, isStatic);
this.sharedClass.disableMethodByName(key);
this.emit('remoteMethodDisabled', this.sharedClass, key);
};
@ -544,10 +532,10 @@ module.exports = function(registry) {
};
Model.belongsToRemoting = function(relationName, relation, define) {
let modelName = relation.modelTo && relation.modelTo.modelName;
var modelName = relation.modelTo && relation.modelTo.modelName;
modelName = modelName || 'PersistedModel';
const fn = this.prototype[relationName];
const pathName = (relation.options.http && relation.options.http.path) || relationName;
var fn = this.prototype[relationName];
var pathName = (relation.options.http && relation.options.http.path) || relationName;
define('__get__' + relationName, {
isStatic: false,
http: {verb: 'get', path: '/' + pathName},
@ -564,19 +552,17 @@ module.exports = function(registry) {
function convertNullToNotFoundError(toModelName, ctx, cb) {
if (ctx.result !== null) return cb();
const fk = ctx.getArgByName('fk');
const msg = fk ?
g.f('Unknown "%s" id "%s".', toModelName, fk) :
g.f('No "%s" instance(s) found', toModelName);
const error = new Error(msg);
var fk = ctx.getArgByName('fk');
var msg = g.f('Unknown "%s" id "%s".', toModelName, fk);
var error = new Error(msg);
error.statusCode = error.status = 404;
error.code = 'MODEL_NOT_FOUND';
cb(error);
}
Model.hasOneRemoting = function(relationName, relation, define) {
const pathName = (relation.options.http && relation.options.http.path) || relationName;
const toModelName = relation.modelTo.modelName;
var pathName = (relation.options.http && relation.options.http.path) || relationName;
var toModelName = relation.modelTo.modelName;
define('__get__' + relationName, {
isStatic: false,
@ -633,10 +619,10 @@ module.exports = function(registry) {
};
Model.hasManyRemoting = function(relationName, relation, define) {
const pathName = (relation.options.http && relation.options.http.path) || relationName;
const toModelName = relation.modelTo.modelName;
var pathName = (relation.options.http && relation.options.http.path) || relationName;
var toModelName = relation.modelTo.modelName;
const findByIdFunc = this.prototype['__findById__' + relationName];
var findByIdFunc = this.prototype['__findById__' + relationName];
define('__findById__' + relationName, {
isStatic: false,
http: {verb: 'get', path: '/' + pathName + '/:fk'},
@ -655,7 +641,7 @@ module.exports = function(registry) {
rest: {after: convertNullToNotFoundError.bind(null, toModelName)},
}, findByIdFunc);
const destroyByIdFunc = this.prototype['__destroyById__' + relationName];
var destroyByIdFunc = this.prototype['__destroyById__' + relationName];
define('__destroyById__' + relationName, {
isStatic: false,
http: {verb: 'delete', path: '/' + pathName + '/:fk'},
@ -673,7 +659,7 @@ module.exports = function(registry) {
returns: [],
}, destroyByIdFunc);
const updateByIdFunc = this.prototype['__updateById__' + relationName];
var updateByIdFunc = this.prototype['__updateById__' + relationName];
define('__updateById__' + relationName, {
isStatic: false,
http: {verb: 'put', path: '/' + pathName + '/:fk'},
@ -691,9 +677,9 @@ module.exports = function(registry) {
}, updateByIdFunc);
if (relation.modelThrough || relation.type === 'referencesMany') {
const modelThrough = relation.modelThrough || relation.modelTo;
var modelThrough = relation.modelThrough || relation.modelTo;
const accepts = [];
var accepts = [];
if (relation.type === 'hasMany' && relation.modelThrough) {
// Restrict: only hasManyThrough relation can have additional properties
accepts.push({
@ -702,7 +688,7 @@ module.exports = function(registry) {
});
}
const addFunc = this.prototype['__link__' + relationName];
var addFunc = this.prototype['__link__' + relationName];
define('__link__' + relationName, {
isStatic: false,
http: {verb: 'put', path: '/' + pathName + '/rel/:fk'},
@ -718,7 +704,7 @@ module.exports = function(registry) {
returns: {arg: relationName, type: modelThrough.modelName, root: true},
}, addFunc);
const removeFunc = this.prototype['__unlink__' + relationName];
var removeFunc = this.prototype['__unlink__' + relationName];
define('__unlink__' + relationName, {
isStatic: false,
http: {verb: 'delete', path: '/' + pathName + '/rel/:fk'},
@ -738,7 +724,7 @@ module.exports = function(registry) {
// FIXME: [rfeng] How to map a function with callback(err, true|false) to HEAD?
// true --> 200 and false --> 404?
const existsFunc = this.prototype['__exists__' + relationName];
var existsFunc = this.prototype['__exists__' + relationName];
define('__exists__' + relationName, {
isStatic: false,
http: {verb: 'head', path: '/' + pathName + '/rel/:fk'},
@ -758,10 +744,10 @@ module.exports = function(registry) {
// After hook to map exists to 200/404 for HEAD
after: function(ctx, cb) {
if (ctx.result === false) {
const modelName = ctx.method.sharedClass.name;
const id = ctx.getArgByName('id');
const msg = g.f('Unknown "%s" {{id}} "%s".', modelName, id);
const error = new Error(msg);
var modelName = ctx.method.sharedClass.name;
var id = ctx.getArgByName('id');
var msg = g.f('Unknown "%s" {{id}} "%s".', modelName, id);
var error = new Error(msg);
error.statusCode = error.status = 404;
error.code = 'MODEL_NOT_FOUND';
cb(error);
@ -775,17 +761,17 @@ module.exports = function(registry) {
};
Model.scopeRemoting = function(scopeName, scope, define) {
const pathName =
var pathName =
(scope.options && scope.options.http && scope.options.http.path) || scopeName;
let modelTo = scope.modelTo;
var modelTo = scope.modelTo;
const isStatic = scope.isStatic;
let toModelName = scope.modelTo.modelName;
var isStatic = scope.isStatic;
var toModelName = scope.modelTo.modelName;
// https://github.com/strongloop/loopback/issues/811
// Check if the scope is for a hasMany relation
const relation = this.relations[scopeName];
var relation = this.relations[scopeName];
if (relation && relation.modelTo) {
// For a relation with through model, the toModelName should be the one
// from the target model
@ -886,22 +872,22 @@ module.exports = function(registry) {
}
options = options || {};
const regExp = /^__([^_]+)__([^_]+)$/;
const relation = this.relations[relationName];
var regExp = /^__([^_]+)__([^_]+)$/;
var relation = this.relations[relationName];
if (relation && relation._nestRemotingProcessed) {
return; // Prevent unwanted circular traversals!
} else if (relation && relation.modelTo && relation.modelTo.sharedClass) {
relation._nestRemotingProcessed = true;
const self = this;
const sharedClass = this.sharedClass;
const sharedToClass = relation.modelTo.sharedClass;
const toModelName = relation.modelTo.modelName;
var self = this;
var sharedClass = this.sharedClass;
var sharedToClass = relation.modelTo.sharedClass;
var toModelName = relation.modelTo.modelName;
const pathName = options.pathName || relation.options.path || relationName;
const paramName = options.paramName || 'nk';
var pathName = options.pathName || relation.options.path || relationName;
var paramName = options.paramName || 'nk';
const http = [].concat(sharedToClass.http || [])[0];
let httpPath, acceptArgs;
var http = [].concat(sharedToClass.http || [])[0];
var httpPath, acceptArgs;
if (relation.multiple) {
httpPath = pathName + '/:' + paramName;
@ -923,30 +909,30 @@ module.exports = function(registry) {
// A method should return the method name to use, if it is to be
// included as a nested method - a falsy return value will skip.
const filter = filterCallback || options.filterMethod || function(method, relation) {
const matches = method.name.match(regExp);
var filter = filterCallback || options.filterMethod || function(method, relation) {
var matches = method.name.match(regExp);
if (matches) {
return '__' + matches[1] + '__' + relation.name + '__' + matches[2];
}
};
sharedToClass.methods().forEach(function(method) {
let methodName;
var methodName;
if (!method.isStatic && (methodName = filter(method, relation))) {
const prefix = relation.multiple ? '__findById__' : '__get__';
const getterName = options.getterName || (prefix + relationName);
var prefix = relation.multiple ? '__findById__' : '__get__';
var getterName = options.getterName || (prefix + relationName);
const getterFn = relation.modelFrom.prototype[getterName];
var getterFn = relation.modelFrom.prototype[getterName];
if (typeof getterFn !== 'function') {
throw new Error(g.f('Invalid remote method: `%s`', getterName));
}
const nestedFn = relation.modelTo.prototype[method.name];
var nestedFn = relation.modelTo.prototype[method.name];
if (typeof nestedFn !== 'function') {
throw new Error(g.f('Invalid remote method: `%s`', method.name));
}
const opts = {};
var opts = {};
opts.accepts = acceptArgs.concat(method.accepts || []);
opts.returns = [].concat(method.returns || []);
@ -956,10 +942,10 @@ module.exports = function(registry) {
opts.rest.delegateTo = method;
opts.http = [];
const routes = [].concat(method.http || []);
var routes = [].concat(method.http || []);
routes.forEach(function(route) {
if (route.path) {
const copy = extend({}, route);
var copy = extend({}, route);
copy.path = httpPath + route.path;
opts.http.push(copy);
}
@ -1017,19 +1003,19 @@ module.exports = function(registry) {
if (options.hooks === false) return; // don't inherit before/after hooks
self.once('mounted', function(app, sc, remotes) {
const listenerTree = extend({}, remotes.listenerTree || {});
var listenerTree = extend({}, remotes.listenerTree || {});
listenerTree.before = listenerTree.before || {};
listenerTree.after = listenerTree.after || {};
const beforeListeners = listenerTree.before[toModelName] || {};
const afterListeners = listenerTree.after[toModelName] || {};
var beforeListeners = listenerTree.before[toModelName] || {};
var afterListeners = listenerTree.after[toModelName] || {};
sharedClass.methods().forEach(function(method) {
const delegateTo = method.rest && method.rest.delegateTo;
var delegateTo = method.rest && method.rest.delegateTo;
if (delegateTo && delegateTo.ctor == relation.modelTo) {
const before = method.isStatic ? beforeListeners : beforeListeners['prototype'];
const after = method.isStatic ? afterListeners : afterListeners['prototype'];
const m = method.isStatic ? method.name : 'prototype.' + method.name;
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.name]) {
self.beforeRemote(m, function(ctx, result, next) {
before[delegateTo.name]._listeners.call(null, ctx, next);
@ -1044,7 +1030,7 @@ module.exports = function(registry) {
});
});
} else {
const msg = g.f('Relation `%s` does not exist for model `%s`', relationName, this.modelName);
var msg = g.f('Relation `%s` does not exist for model `%s`', relationName, this.modelName);
throw new Error(msg);
}
};

View File

@ -1,4 +1,4 @@
// Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Copyright IBM Corp. 2014,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
@ -7,20 +7,20 @@
* Module Dependencies.
*/
'use strict';
const g = require('./globalize');
const runtime = require('./runtime');
const assert = require('assert');
const async = require('async');
const deprecated = require('depd')('loopback');
const debug = require('debug')('loopback:persisted-model');
const PassThrough = require('stream').PassThrough;
const utils = require('./utils');
const filterNodes = require('loopback-filters');
var g = require('./globalize');
var runtime = require('./runtime');
var assert = require('assert');
var async = require('async');
var deprecated = require('depd')('loopback');
var debug = require('debug')('loopback:persisted-model');
var PassThrough = require('stream').PassThrough;
var utils = require('./utils');
var filterNodes = require('loopback-filters');
const REPLICATION_CHUNK_SIZE = -1;
var REPLICATION_CHUNK_SIZE = -1;
module.exports = function(registry) {
const Model = registry.getModel('Model');
var Model = registry.getModel('Model');
/**
* Extends Model with basic query and CRUD support.
@ -38,7 +38,7 @@ module.exports = function(registry) {
* @class PersistedModel
*/
const PersistedModel = Model.extend('PersistedModel');
var PersistedModel = Model.extend('PersistedModel');
/*!
* Setup the `PersistedModel` constructor.
@ -48,7 +48,7 @@ module.exports = function(registry) {
// call Model.setup first
Model.setup.call(this);
const PersistedModel = this;
var PersistedModel = this;
// enable change tracking (usually for replication)
if (this.settings.trackChanges) {
@ -72,7 +72,7 @@ module.exports = function(registry) {
g.f('Cannot call %s.%s().' +
' The %s method has not been setup.' +
' The {{PersistedModel}} has not been correctly attached to a {{DataSource}}!',
modelName, methodName, methodName),
modelName, methodName, methodName)
);
}
@ -85,10 +85,10 @@ module.exports = function(registry) {
function convertNullToNotFoundError(ctx, cb) {
if (ctx.result !== null) return cb();
const modelName = ctx.method.sharedClass.name;
const id = ctx.getArgByName('id');
const msg = g.f('Unknown "%s" {{id}} "%s".', modelName, id);
const error = new Error(msg);
var modelName = ctx.method.sharedClass.name;
var id = ctx.getArgByName('id');
var msg = g.f('Unknown "%s" {{id}} "%s".', modelName, id);
var error = new Error(msg);
error.statusCode = error.status = 404;
error.code = 'MODEL_NOT_FOUND';
cb(error);
@ -403,7 +403,7 @@ module.exports = function(registry) {
*/
PersistedModel.prototype.save = function(options, callback) {
const Model = this.constructor;
var Model = this.constructor;
if (typeof options == 'function') {
callback = options;
@ -421,9 +421,9 @@ module.exports = function(registry) {
options.throws = false;
}
const inst = this;
const data = inst.toObject(true);
const id = this.getId();
var inst = this;
var data = inst.toObject(true);
var id = this.getId();
if (!id) {
return Model.create(this, callback);
@ -438,7 +438,7 @@ module.exports = function(registry) {
if (valid) {
save();
} else {
const err = new Model.ValidationError(inst);
var err = new Model.ValidationError(inst);
// throws option is dangerous for async usage
if (options.throws) {
throw err;
@ -581,7 +581,7 @@ module.exports = function(registry) {
*/
PersistedModel.prototype.setId = function(val) {
const ds = this.getDataSource();
var ds = this.getDataSource();
this[this.getIdName()] = val;
};
@ -592,7 +592,7 @@ module.exports = function(registry) {
*/
PersistedModel.prototype.getId = function() {
const data = this.toObject();
var data = this.toObject();
if (!data) return;
return data[this.getIdName()];
};
@ -614,8 +614,8 @@ module.exports = function(registry) {
*/
PersistedModel.getIdName = function() {
const Model = this;
const ds = Model.getDataSource();
var Model = this;
var ds = Model.getDataSource();
if (ds.idName) {
return ds.idName(Model.modelName);
@ -625,9 +625,9 @@ module.exports = function(registry) {
};
PersistedModel.setupRemoting = function() {
const PersistedModel = this;
const typeName = PersistedModel.modelName;
const options = PersistedModel.settings;
var PersistedModel = this;
var typeName = PersistedModel.modelName;
var options = PersistedModel.settings;
// if there is atleast one updateOnly property, then we set
// createOnlyInstance flag in __create__ to indicate loopback-swagger
@ -640,7 +640,7 @@ module.exports = function(registry) {
options.replaceOnPUT = options.replaceOnPUT !== false;
function setRemoting(scope, name, options) {
const fn = scope[name];
var fn = scope[name];
fn._delegate = true;
options.isStatic = scope === PersistedModel;
PersistedModel.remoteMethod(name, options);
@ -662,7 +662,7 @@ module.exports = function(registry) {
http: {verb: 'post', path: '/'},
});
const upsertOptions = {
var upsertOptions = {
aliases: ['upsert', 'updateOrCreate'],
description: 'Patch an existing model instance or insert a new one ' +
'into the data source.',
@ -683,7 +683,7 @@ module.exports = function(registry) {
}
setRemoting(PersistedModel, 'patchOrCreate', upsertOptions);
const replaceOrCreateOptions = {
var replaceOrCreateOptions = {
description: 'Replace an existing model instance or insert a new one into the data source.',
accessType: 'WRITE',
accepts: [
@ -724,8 +724,7 @@ module.exports = function(registry) {
description: 'Check whether a model instance exists in the data source.',
accessType: 'READ',
accepts: [
{arg: 'id', type: 'any', description: 'Model id', required: true,
http: {source: 'path'}},
{arg: 'id', type: 'any', description: 'Model id', required: true},
{arg: 'options', type: 'object', http: 'optionsFromRequest'},
],
returns: {arg: 'exists', type: 'boolean'},
@ -741,10 +740,10 @@ module.exports = function(registry) {
return cb();
}
if (!ctx.result.exists) {
const modelName = ctx.method.sharedClass.name;
const id = ctx.getArgByName('id');
const msg = 'Unknown "' + modelName + '" id "' + id + '".';
const error = new Error(msg);
var modelName = ctx.method.sharedClass.name;
var id = ctx.getArgByName('id');
var msg = 'Unknown "' + modelName + '" id "' + id + '".';
var error = new Error(msg);
error.statusCode = error.status = 404;
error.code = 'MODEL_NOT_FOUND';
cb(error);
@ -772,7 +771,7 @@ module.exports = function(registry) {
rest: {after: convertNullToNotFoundError},
});
const replaceByIdOptions = {
var replaceByIdOptions = {
description: 'Replace attributes for a model instance and persist it into the data source.',
accessType: 'WRITE',
accepts: [
@ -798,9 +797,7 @@ module.exports = function(registry) {
accepts: [
{arg: 'filter', type: 'object', description:
'Filter defining fields, where, include, order, offset, and limit - must be a ' +
'JSON-encoded string (`{"where":{"something":"value"}}`). ' +
'See https://loopback.io/doc/en/lb3/Querying-data.html#using-stringified-json-in-rest-queries ' +
'for more details.'},
'JSON-encoded string ({"something":"value"})'},
{arg: 'options', type: 'object', http: 'optionsFromRequest'},
],
returns: {arg: 'data', type: [typeName], root: true},
@ -813,9 +810,7 @@ module.exports = function(registry) {
accepts: [
{arg: 'filter', type: 'object', description:
'Filter defining fields, where, include, order, offset, and limit - must be a ' +
'JSON-encoded string (`{"where":{"something":"value"}}`). ' +
'See https://loopback.io/doc/en/lb3/Querying-data.html#using-stringified-json-in-rest-queries ' +
'for more details.'},
'JSON-encoded string ({"something":"value"})'},
{arg: 'options', type: 'object', http: 'optionsFromRequest'},
],
returns: {arg: 'data', type: typeName, root: true},
@ -889,7 +884,7 @@ module.exports = function(registry) {
http: {verb: 'get', path: '/count'},
});
const updateAttributesOptions = {
var updateAttributesOptions = {
aliases: ['updateAttributes'],
description: 'Patch attributes for a model instance and persist it into ' +
'the data source.',
@ -1038,7 +1033,7 @@ module.exports = function(registry) {
*/
PersistedModel.diff = function(since, remoteChanges, callback) {
const Change = this.getChangeModel();
var Change = this.getChangeModel();
Change.diff(this.modelName, since, remoteChanges, callback);
};
@ -1064,9 +1059,9 @@ module.exports = function(registry) {
filter = {};
}
const idName = this.dataSource.idName(this.modelName);
const Change = this.getChangeModel();
const model = this;
var idName = this.dataSource.idName(this.modelName);
var Change = this.getChangeModel();
var model = this;
const changeFilter = this.createChangeFilter(since, filter);
filter = filter || {};
@ -1078,13 +1073,13 @@ module.exports = function(registry) {
Change.find(changeFilter, function(err, changes) {
if (err) return callback(err);
if (!Array.isArray(changes) || changes.length === 0) return callback(null, []);
const ids = changes.map(function(change) {
var ids = changes.map(function(change) {
return change.getModelId();
});
filter.where[idName] = {inq: ids};
model.find(filter, function(err, models) {
if (err) return callback(err);
const modelIds = models.map(function(m) {
var modelIds = models.map(function(m) {
return m[idName].toString();
});
callback(null, changes.filter(function(ch) {
@ -1102,7 +1097,7 @@ module.exports = function(registry) {
*/
PersistedModel.checkpoint = function(cb) {
const Checkpoint = this.getChangeModel().getCheckpointModel();
var Checkpoint = this.getChangeModel().getCheckpointModel();
Checkpoint.bumpLastSeq(cb);
};
@ -1115,7 +1110,7 @@ module.exports = function(registry) {
*/
PersistedModel.currentCheckpoint = function(cb) {
const Checkpoint = this.getChangeModel().getCheckpointModel();
var Checkpoint = this.getChangeModel().getCheckpointModel();
Checkpoint.current(cb);
};
@ -1136,7 +1131,7 @@ module.exports = function(registry) {
*/
PersistedModel.replicate = function(since, targetModel, options, callback) {
const lastArg = arguments[arguments.length - 1];
var lastArg = arguments[arguments.length - 1];
if (typeof lastArg === 'function' && arguments.length > 1) {
callback = lastArg;
@ -1157,7 +1152,7 @@ module.exports = function(registry) {
options = options || {};
const sourceModel = this;
var sourceModel = this;
callback = callback || utils.createPromiseCallback();
debug('replicating %s since %s to %s since %s',
@ -1181,7 +1176,7 @@ module.exports = function(registry) {
// until no changes were replicated, but at most MAX_ATTEMPTS times
// to prevent starvation. In most cases, the second run will find no changes
// to replicate and we are done.
const MAX_ATTEMPTS = 3;
var MAX_ATTEMPTS = 3;
run(1, since);
return callback.promise;
@ -1191,7 +1186,7 @@ module.exports = function(registry) {
tryReplicate(sourceModel, targetModel, since, options, next);
function next(err, conflicts, cps, updates) {
const finished = err || conflicts.length ||
var finished = err || conflicts.length ||
!updates || updates.length === 0 ||
attempt >= MAX_ATTEMPTS;
@ -1203,10 +1198,10 @@ module.exports = function(registry) {
};
function tryReplicate(sourceModel, targetModel, since, options, callback) {
const Change = sourceModel.getChangeModel();
const TargetChange = targetModel.getChangeModel();
const changeTrackingEnabled = Change && TargetChange;
let replicationChunkSize = REPLICATION_CHUNK_SIZE;
var Change = sourceModel.getChangeModel();
var TargetChange = targetModel.getChangeModel();
var changeTrackingEnabled = Change && TargetChange;
var replicationChunkSize = REPLICATION_CHUNK_SIZE;
if (sourceModel.settings && sourceModel.settings.replicationChunkSize) {
replicationChunkSize = sourceModel.settings.replicationChunkSize;
@ -1214,12 +1209,12 @@ module.exports = function(registry) {
assert(
changeTrackingEnabled,
'You must enable change tracking before replicating',
'You must enable change tracking before replicating'
);
let diff, updates, newSourceCp, newTargetCp;
var diff, updates, newSourceCp, newTargetCp;
const tasks = [
var tasks = [
checkpoints,
getSourceChanges,
getDiffFromTarget,
@ -1236,7 +1231,7 @@ module.exports = function(registry) {
function(filter, pagingCallback) {
sourceModel.changes(since.source, filter, pagingCallback);
},
debug.enabled ? log : cb,
debug.enabled ? log : cb
);
function log(err, result) {
@ -1254,7 +1249,7 @@ module.exports = function(registry) {
function(smallArray, chunkCallback) {
return targetModel.diff(since.target, smallArray, chunkCallback);
},
debug.enabled ? log : cb,
debug.enabled ? log : cb
);
function log(err, result) {
@ -1283,7 +1278,7 @@ module.exports = function(registry) {
function(smallArray, chunkCallback) {
return sourceModel.createUpdates(smallArray, chunkCallback);
},
cb,
cb
);
} else {
// nothing to replicate
@ -1304,7 +1299,7 @@ module.exports = function(registry) {
});
},
function(notUsed, err) {
const conflicts = err && err.details && err.details.conflicts;
var conflicts = err && err.details && err.details.conflicts;
if (conflicts && err.statusCode == 409) {
diff.conflicts = conflicts;
// filter out updates that were not applied
@ -1316,12 +1311,12 @@ module.exports = function(registry) {
return cb();
}
cb(err);
},
}
);
}
function checkpoints() {
const cb = arguments[arguments.length - 1];
var cb = arguments[arguments.length - 1];
sourceModel.checkpoint(function(err, source) {
if (err) return cb(err);
newSourceCp = source.seq;
@ -1345,9 +1340,9 @@ module.exports = function(registry) {
debug('\t\tnew checkpoints: { source: %j, target: %j }',
newSourceCp, newTargetCp);
const conflicts = diff.conflicts.map(function(change) {
var conflicts = diff.conflicts.map(function(change) {
return new Change.Conflict(
change.modelId, sourceModel, targetModel,
change.modelId, sourceModel, targetModel
);
});
@ -1356,7 +1351,7 @@ module.exports = function(registry) {
}
if (callback) {
const newCheckpoints = {source: newSourceCp, target: newTargetCp};
var newCheckpoints = {source: newSourceCp, target: newTargetCp};
callback(null, conflicts, newCheckpoints, updates);
}
}
@ -1371,15 +1366,15 @@ module.exports = function(registry) {
*/
PersistedModel.createUpdates = function(deltas, cb) {
const Change = this.getChangeModel();
const updates = [];
const Model = this;
const tasks = [];
var Change = this.getChangeModel();
var updates = [];
var Model = this;
var tasks = [];
deltas.forEach(function(change) {
change = new Change(change);
const type = change.type();
const update = {type: type, change: change};
var type = change.type();
var update = {type: type, change: change};
switch (type) {
case Change.CREATE:
case Change.UPDATE:
@ -1423,12 +1418,12 @@ module.exports = function(registry) {
*/
PersistedModel.bulkUpdate = function(updates, options, callback) {
const tasks = [];
const Model = this;
const Change = this.getChangeModel();
const conflicts = [];
var tasks = [];
var Model = this;
var Change = this.getChangeModel();
var conflicts = [];
const lastArg = arguments[arguments.length - 1];
var lastArg = arguments[arguments.length - 1];
if (typeof lastArg === 'function' && arguments.length > 1) {
callback = lastArg;
@ -1444,8 +1439,8 @@ module.exports = function(registry) {
if (err) return callback(err);
updates.forEach(function(update) {
const id = update.change.modelId;
const current = currentMap[id];
var id = update.change.modelId;
var current = currentMap[id];
switch (update.type) {
case Change.UPDATE:
tasks.push(function(cb) {
@ -1480,13 +1475,13 @@ module.exports = function(registry) {
};
function buildLookupOfAffectedModelData(Model, updates, callback) {
const idName = Model.dataSource.idName(Model.modelName);
const affectedIds = updates.map(function(u) { return u.change.modelId; });
const whereAffected = {};
var idName = Model.dataSource.idName(Model.modelName);
var affectedIds = updates.map(function(u) { return u.change.modelId; });
var whereAffected = {};
whereAffected[idName] = {inq: affectedIds};
Model.find({where: whereAffected}, function(err, affectedList) {
if (err) return callback(err);
const dataLookup = {};
var dataLookup = {};
affectedList.forEach(function(it) {
dataLookup[it[idName]] = it;
});
@ -1495,8 +1490,8 @@ module.exports = function(registry) {
}
function applyUpdate(Model, id, current, data, change, conflicts, options, cb) {
const Change = Model.getChangeModel();
const rev = current ? Change.revisionForInst(current) : null;
var Change = Model.getChangeModel();
var rev = current ? Change.revisionForInst(current) : null;
if (rev !== change.prev) {
debug('Detected non-rectified change of %s %j',
@ -1515,7 +1510,7 @@ module.exports = function(registry) {
Model.updateAll(current.toObject(), data, options, function(err, result) {
if (err) return cb(err);
const count = result && result.count;
var count = result && result.count;
switch (count) {
case 1:
// The happy path, exactly one record was updated
@ -1535,7 +1530,7 @@ module.exports = function(registry) {
return cb(new Error(
g.f('Cannot apply bulk updates, ' +
'the connector does not correctly report ' +
'the number of updated records.'),
'the number of updated records.')
));
default:
@ -1543,7 +1538,7 @@ module.exports = function(registry) {
Model.modelName, count);
return cb(new Error(
g.f('Bulk update failed, the connector has modified unexpected ' +
'number of records: %s', JSON.stringify(count)),
'number of records: %s', JSON.stringify(count))
));
}
});
@ -1573,7 +1568,7 @@ module.exports = function(registry) {
Model.modelName, id);
conflicts.push(change);
const Change = Model.getChangeModel();
var Change = Model.getChangeModel();
return Change.rectifyModelChanges(Model.modelName, [id], cb);
}
}
@ -1585,8 +1580,8 @@ module.exports = function(registry) {
return cb();
}
const Change = Model.getChangeModel();
const rev = Change.revisionForInst(current);
var Change = Model.getChangeModel();
var rev = Change.revisionForInst(current);
if (rev !== change.prev) {
debug('Detected non-rectified change of %s %j',
Model.modelName, id);
@ -1599,7 +1594,7 @@ module.exports = function(registry) {
Model.deleteAll(current.toObject(), options, function(err, result) {
if (err) return cb(err);
const count = result && result.count;
var count = result && result.count;
switch (count) {
case 1:
// The happy path, exactly one record was updated
@ -1619,7 +1614,7 @@ module.exports = function(registry) {
return cb(new Error(
g.f('Cannot apply bulk updates, ' +
'the connector does not correctly report ' +
'the number of deleted records.'),
'the number of deleted records.')
));
default:
@ -1627,7 +1622,7 @@ module.exports = function(registry) {
Model.modelName, count);
return cb(new Error(
g.f('Bulk update failed, the connector has deleted unexpected ' +
'number of records: %s', JSON.stringify(count)),
'number of records: %s', JSON.stringify(count))
));
}
});
@ -1640,8 +1635,8 @@ module.exports = function(registry) {
*/
PersistedModel.getChangeModel = function() {
const changeModel = this.Change;
const isSetup = changeModel && changeModel.dataSource;
var changeModel = this.Change;
var isSetup = changeModel && changeModel.dataSource;
assert(isSetup, 'Cannot get a setup Change model for ' + this.modelName);
@ -1657,15 +1652,15 @@ module.exports = function(registry) {
*/
PersistedModel.getSourceId = function(cb) {
const dataSource = this.dataSource;
var dataSource = this.dataSource;
if (!dataSource) {
this.once('dataSourceAttached', this.getSourceId.bind(this, cb));
}
assert(
dataSource.connector.name,
'Model.getSourceId: cannot get id without dataSource.connector.name',
'Model.getSourceId: cannot get id without dataSource.connector.name'
);
const id = [dataSource.connector.name, this.modelName].join('-');
var id = [dataSource.connector.name, this.modelName].join('-');
cb(null, id);
};
@ -1674,17 +1669,17 @@ module.exports = function(registry) {
*/
PersistedModel.enableChangeTracking = function() {
const Model = this;
const Change = this.Change || this._defineChangeModel();
const cleanupInterval = Model.settings.changeCleanupInterval || 30000;
var Model = this;
var Change = this.Change || this._defineChangeModel();
var cleanupInterval = Model.settings.changeCleanupInterval || 30000;
assert(this.dataSource, 'Cannot enableChangeTracking(): ' + this.modelName +
' is not attached to a dataSource');
const idName = this.getIdName();
const idProp = this.definition.properties[idName];
const idType = idProp && idProp.type;
const idDefn = idProp && idProp.defaultFn;
var idName = this.getIdName();
var idProp = this.definition.properties[idName];
var idType = idProp && idProp.type;
var idDefn = idProp && idProp.defaultFn;
if (idType !== String || !(idDefn === 'uuid' || idDefn === 'guid')) {
deprecated('The model ' + this.modelName + ' is tracking changes, ' +
'which requires a string id with GUID/UUID default value.');
@ -1714,8 +1709,8 @@ module.exports = function(registry) {
};
function rectifyOnSave(ctx, next) {
const instance = ctx.instance || ctx.currentInstance;
const id = instance ? instance.getId() :
var instance = ctx.instance || ctx.currentInstance;
var id = instance ? instance.getId() :
getIdFromWhereByModelId(ctx.Model, ctx.where);
if (debug.enabled) {
@ -1740,7 +1735,7 @@ module.exports = function(registry) {
}
function rectifyOnDelete(ctx, next) {
const id = ctx.instance ? ctx.instance.getId() :
var id = ctx.instance ? ctx.instance.getId() :
getIdFromWhereByModelId(ctx.Model, ctx.where);
if (debug.enabled) {
@ -1764,10 +1759,10 @@ module.exports = function(registry) {
}
function getIdFromWhereByModelId(Model, where) {
const idName = Model.getIdName();
var idName = Model.getIdName();
if (!(idName in where)) return undefined;
const id = where[idName];
var id = where[idName];
// TODO(bajtos) support object values that are not LB conditions
if (typeof id === 'string' || typeof id === 'number') {
return id;
@ -1776,7 +1771,7 @@ module.exports = function(registry) {
}
PersistedModel._defineChangeModel = function() {
const BaseChangeModel = this.registry.getModel('Change');
var BaseChangeModel = this.registry.getModel('Change');
assert(BaseChangeModel,
'Change model must be defined before enabling change replication');
@ -1786,7 +1781,7 @@ module.exports = function(registry) {
this.Change = BaseChangeModel.extend(
this.modelName + '-change',
additionalChangeModelProperties,
{trackModel: this},
{trackModel: this}
);
if (this.dataSource) {
@ -1794,7 +1789,7 @@ module.exports = function(registry) {
}
// Re-attach related models whenever our datasource is changed.
const self = this;
var self = this;
this.on('dataSourceAttached', function() {
attachRelatedModels(self);
});
@ -1832,17 +1827,17 @@ module.exports = function(registry) {
*/
PersistedModel.rectifyChange = function(id, callback) {
const Change = this.getChangeModel();
var Change = this.getChangeModel();
Change.rectifyModelChanges(this.modelName, [id], callback);
};
PersistedModel.findLastChange = function(id, cb) {
const Change = this.getChangeModel();
var Change = this.getChangeModel();
Change.findOne({where: {modelId: id}}, cb);
};
PersistedModel.updateLastChange = function(id, data, cb) {
const self = this;
var self = this;
this.findLastChange(id, function(err, inst) {
if (err) return cb(err);
if (!inst) {
@ -1873,9 +1868,9 @@ module.exports = function(registry) {
}
cb = cb || utils.createPromiseCallback();
const idName = this.getIdName();
const Model = this;
const changes = new PassThrough({objectMode: true});
var idName = this.getIdName();
var Model = this;
var changes = new PassThrough({objectMode: true});
changes._destroy = function() {
changes.end();
@ -1900,31 +1895,31 @@ module.exports = function(registry) {
return cb.promise;
function changeHandler(ctx, next) {
const change = createChangeObject(ctx, 'save');
var change = createChangeObject(ctx, 'save');
if (change) {
changes.write(change);
}
next();
}
};
function deleteHandler(ctx, next) {
const change = createChangeObject(ctx, 'delete');
var change = createChangeObject(ctx, 'delete');
if (change) {
changes.write(change);
}
next();
}
};
function createChangeObject(ctx, type) {
const where = ctx.where;
let data = ctx.instance || ctx.data;
const whereId = where && where[idName];
var where = ctx.where;
var data = ctx.instance || ctx.data;
var whereId = where && where[idName];
// the data includes the id
// or the where includes the id
let target;
var target;
if (data && (data[idName] || data[idName] === 0)) {
target = data[idName];
@ -1932,18 +1927,18 @@ module.exports = function(registry) {
target = where[idName];
}
const hasTarget = target === 0 || !!target;
var hasTarget = target === 0 || !!target;
// apply filtering if options is set
if (options) {
const filtered = filterNodes([data], options);
var filtered = filterNodes([data], options);
if (filtered.length !== 1) {
return null;
}
data = filtered[0];
}
const change = {
var change = {
target: target,
where: where,
data: data,

View File

@ -1,17 +1,17 @@
// Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Copyright IBM Corp. 2014,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const g = require('./globalize');
const assert = require('assert');
const extend = require('util')._extend;
const juggler = require('loopback-datasource-juggler');
const debug = require('debug')('loopback:registry');
const DataSource = juggler.DataSource;
const ModelBuilder = juggler.ModelBuilder;
const deprecated = require('depd')('strong-remoting');
var g = require('./globalize');
var assert = require('assert');
var extend = require('util')._extend;
var juggler = require('loopback-datasource-juggler');
var debug = require('debug')('loopback:registry');
var DataSource = juggler.DataSource;
var ModelBuilder = juggler.ModelBuilder;
var deprecated = require('depd')('strong-remoting');
module.exports = Registry;
@ -97,7 +97,7 @@ function Registry() {
Registry.prototype.createModel = function(name, properties, options) {
if (arguments.length === 1 && typeof name === 'object') {
const config = name;
var config = name;
name = config.name;
properties = config.properties;
options = buildModelOptionsFromConfig(config);
@ -107,10 +107,10 @@ Registry.prototype.createModel = function(name, properties, options) {
}
options = options || {};
let BaseModel = options.base || options.super;
var BaseModel = options.base || options.super;
if (typeof BaseModel === 'string') {
const baseName = BaseModel;
var baseName = BaseModel;
BaseModel = this.findModel(BaseModel);
if (!BaseModel) {
throw new Error(g.f('Model not found: model `%s` is extending an unknown model `%s`.',
@ -119,7 +119,7 @@ Registry.prototype.createModel = function(name, properties, options) {
}
BaseModel = BaseModel || this.getModel('PersistedModel');
const model = BaseModel.extend(name, properties, options);
var model = BaseModel.extend(name, properties, options);
model.registry = this;
this._defineRemoteMethods(model, model.settings.methods);
@ -128,8 +128,8 @@ Registry.prototype.createModel = function(name, properties, options) {
};
function buildModelOptionsFromConfig(config) {
const options = extend({}, config.options);
for (const key in config) {
var options = extend({}, config.options);
for (var key in config) {
if (['name', 'properties', 'options'].indexOf(key) !== -1) {
// Skip items which have special meaning
continue;
@ -152,7 +152,7 @@ function buildModelOptionsFromConfig(config) {
* @param {Object} acl
*/
function addACL(acls, acl) {
for (let i = 0, n = acls.length; i < n; i++) {
for (var i = 0, n = acls.length; i < n; i++) {
// Check if there is a matching acl to be overriden
if (acls[i].property === acl.property &&
acls[i].accessType === acl.accessType &&
@ -176,14 +176,14 @@ function addACL(acls, acl) {
*/
Registry.prototype.configureModel = function(ModelCtor, config) {
const settings = ModelCtor.settings;
const modelName = ModelCtor.modelName;
var settings = ModelCtor.settings;
var modelName = ModelCtor.modelName;
ModelCtor.config = config;
// Relations
if (typeof config.relations === 'object' && config.relations !== null) {
const relations = settings.relations = settings.relations || {};
var relations = settings.relations = settings.relations || {};
Object.keys(config.relations).forEach(function(key) {
// FIXME: [rfeng] We probably should check if the relation exists
relations[key] = extend(relations[key] || {}, config.relations[key]);
@ -195,7 +195,7 @@ Registry.prototype.configureModel = function(ModelCtor, config) {
// ACLs
if (Array.isArray(config.acls)) {
const acls = settings.acls = settings.acls || [];
var acls = settings.acls = settings.acls || [];
config.acls.forEach(function(acl) {
addACL(acls, acl);
});
@ -205,7 +205,7 @@ Registry.prototype.configureModel = function(ModelCtor, config) {
}
// Settings
const excludedProperties = {
var excludedProperties = {
base: true,
'super': true,
relations: true,
@ -213,7 +213,7 @@ Registry.prototype.configureModel = function(ModelCtor, config) {
dataSource: true,
};
if (typeof config.options === 'object' && config.options !== null) {
for (const p in config.options) {
for (var p in config.options) {
if (!(p in excludedProperties)) {
settings[p] = config.options[p];
} else {
@ -244,17 +244,17 @@ Registry.prototype.configureModel = function(ModelCtor, config) {
g.warn(
'The configuration of `%s` is missing {{`dataSource`}} property.\n' +
'Use `null` or `false` to mark models not attached to any data source.',
modelName,
modelName
);
}
const newMethodNames = config.methods && Object.keys(config.methods);
const hasNewMethods = newMethodNames && newMethodNames.length;
const hasDescendants = this.getModelByType(ModelCtor) !== ModelCtor;
var newMethodNames = config.methods && Object.keys(config.methods);
var hasNewMethods = newMethodNames && newMethodNames.length;
var hasDescendants = this.getModelByType(ModelCtor) !== ModelCtor;
if (hasNewMethods && hasDescendants) {
g.warn(
'Child models of `%s` will not inherit newly defined remote methods %s.',
modelName, newMethodNames,
modelName, newMethodNames
);
}
@ -271,9 +271,9 @@ Registry.prototype._defineRemoteMethods = function(ModelCtor, methods) {
}
Object.keys(methods).forEach(function(key) {
let meta = methods[key];
const m = key.match(/^prototype\.(.*)$/);
const isStatic = !m;
var meta = methods[key];
var m = key.match(/^prototype\.(.*)$/);
var isStatic = !m;
if (typeof meta.isStatic !== 'boolean') {
key = isStatic ? key : m[1];
@ -313,7 +313,7 @@ Registry.prototype.findModel = function(modelName) {
* @header loopback.getModel(modelName)
*/
Registry.prototype.getModel = function(modelName) {
const model = this.findModel(modelName);
var model = this.findModel(modelName);
if (model) return model;
throw new Error(g.f('Model not found: %s', modelName));
@ -329,8 +329,8 @@ Registry.prototype.getModel = function(modelName) {
* @header loopback.getModelByType(modelType)
*/
Registry.prototype.getModelByType = function(modelType) {
const type = typeof modelType;
const accepted = ['function', 'string'];
var type = typeof modelType;
var accepted = ['function', 'string'];
assert(accepted.indexOf(type) > -1,
'The model type must be a constructor or model name');
@ -339,8 +339,8 @@ Registry.prototype.getModelByType = function(modelType) {
modelType = this.getModel(modelType);
}
const models = this.modelBuilder.models;
for (const m in models) {
var models = this.modelBuilder.models;
for (var m in models) {
if (models[m].prototype instanceof modelType) {
return models[m];
}
@ -359,15 +359,15 @@ Registry.prototype.getModelByType = function(modelType) {
*/
Registry.prototype.createDataSource = function(name, options) {
const self = this;
var self = this;
const ds = new DataSource(name, options, self.modelBuilder);
var ds = new DataSource(name, options, self.modelBuilder);
ds.createModel = function(name, properties, settings) {
settings = settings || {};
let BaseModel = settings.base || settings.super;
var BaseModel = settings.base || settings.super;
if (!BaseModel) {
// Check the connector types
const connectorTypes = ds.getTypes();
var connectorTypes = ds.getTypes();
if (Array.isArray(connectorTypes) && connectorTypes.indexOf('db') !== -1) {
// Only set up the base model to PersistedModel if the connector is DB
BaseModel = self.PersistedModel;
@ -376,13 +376,13 @@ Registry.prototype.createDataSource = function(name, options) {
}
settings.base = BaseModel;
}
const ModelCtor = self.createModel(name, properties, settings);
var ModelCtor = self.createModel(name, properties, settings);
ModelCtor.attachTo(ds);
return ModelCtor;
};
if (ds.settings && ds.settings.defaultForType) {
const msg = g.f('{{DataSource}} option {{"defaultForType"}} is no longer supported');
var msg = g.f('{{DataSource}} option {{"defaultForType"}} is no longer supported');
throw new Error(msg);
}
@ -398,7 +398,7 @@ Registry.prototype.createDataSource = function(name, options) {
Registry.prototype.memory = function(name) {
name = name || 'default';
let memory = (
var memory = (
this._memoryDataSources || (this._memoryDataSources = {})
)[name];

View File

@ -1,4 +1,4 @@
// Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Copyright IBM Corp. 2014,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
@ -10,7 +10,7 @@
*/
'use strict';
const runtime = exports;
var runtime = exports;
/**
* True if running in a browser environment; false otherwise.

View File

@ -1,23 +1,23 @@
// Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Copyright IBM Corp. 2014,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const g = require('./globalize');
const assert = require('assert');
const express = require('express');
const merge = require('util')._extend;
const mergePhaseNameLists = require('loopback-phase').mergePhaseNameLists;
const debug = require('debug')('loopback:app');
const stableSortInPlace = require('stable').inplace;
var g = require('./globalize');
var assert = require('assert');
var express = require('express');
var merge = require('util')._extend;
var mergePhaseNameLists = require('loopback-phase').mergePhaseNameLists;
var debug = require('debug')('loopback:app');
var stableSortInPlace = require('stable').inplace;
const BUILTIN_MIDDLEWARE = {builtin: true};
var BUILTIN_MIDDLEWARE = {builtin: true};
const proto = {};
var proto = {};
module.exports = function loopbackExpress() {
const app = express();
var app = express();
app.__expressLazyRouter = app.lazyrouter;
merge(app, proto);
return app;
@ -64,23 +64,23 @@ proto.middlewareFromConfig = function(factory, config) {
if (config.enabled === false)
return;
let params = config.params;
var params = config.params;
if (params === undefined) {
params = [];
} else if (!Array.isArray(params)) {
params = [params];
}
let handler = factory.apply(null, params);
var handler = factory.apply(null, params);
// Check if methods/verbs filter exists
let verbs = config.methods || config.verbs;
var verbs = config.methods || config.verbs;
if (Array.isArray(verbs)) {
verbs = verbs.map(function(verb) {
return verb && verb.toUpperCase();
});
if (verbs.indexOf('ALL') === -1) {
const originalHandler = handler;
var originalHandler = handler;
if (handler.length <= 3) {
// Regular handler
handler = function(req, res, next) {
@ -145,7 +145,7 @@ proto.defineMiddlewarePhases = function(nameOrArray) {
mergePhaseNameLists(this._requestHandlingPhases, nameOrArray);
} else {
// add the new phase before 'routes'
const routesIx = this._requestHandlingPhases.indexOf('routes');
var routesIx = this._requestHandlingPhases.indexOf('routes');
this._requestHandlingPhases.splice(routesIx - 1, 0, nameOrArray);
}
@ -181,10 +181,10 @@ proto.middleware = function(name, paths, handler) {
paths = '/';
}
const fullPhaseName = name;
const handlerName = handler.name || '<anonymous>';
var fullPhaseName = name;
var handlerName = handler.name || '<anonymous>';
const m = name.match(/^(.+):(before|after)$/);
var m = name.match(/^(.+):(before|after)$/);
if (m) {
name = m[1];
}
@ -197,7 +197,7 @@ proto.middleware = function(name, paths, handler) {
this._skipLayerSorting = true;
this.use(paths, handler);
const layer = this._findLayerByHandler(handler);
var layer = this._findLayerByHandler(handler);
if (layer) {
// Set the phase name for sorting
layer.phase = fullPhaseName;
@ -221,20 +221,17 @@ proto.middleware = function(name, paths, handler) {
*/
proto._findLayerByHandler = function(handler) {
// Other handlers can be added to the stack, for example,
// NewRelic adds sentinel handler, and AppDynamics adds
// some additional proxy info. We need to search the stack
for (let k = this._router.stack.length - 1; k >= 0; k--) {
const isOriginal = this._router.stack[k].handle === handler;
const isNewRelic = this._router.stack[k].handle['__NR_original'] === handler;
const isAppDynamics = this._router.stack[k].handle['__appdynamicsProxyInfo__'] &&
this._router.stack[k].handle['__appdynamicsProxyInfo__']['orig'] === handler;
if (isOriginal || isNewRelic || isAppDynamics) {
// NewRelic adds sentinel handler. We need to search the stack
for (var k = this._router.stack.length - 1; k >= 0; k--) {
if (this._router.stack[k].handle === handler ||
// NewRelic replaces the handle and keeps it as __NR_original
this._router.stack[k].handle['__NR_original'] === handler
) {
return this._router.stack[k];
} else {
// Aggressively check if the original handler has been wrapped
// into a new function with a property pointing to the original handler
for (const p in this._router.stack[k].handle) {
for (var p in this._router.stack[k].handle) {
if (this._router.stack[k].handle[p] === handler) {
return this._router.stack[k];
}
@ -246,12 +243,12 @@ proto._findLayerByHandler = function(handler) {
// Install our custom PhaseList-based handler into the app
proto.lazyrouter = function() {
const self = this;
var self = this;
if (self._router) return;
self.__expressLazyRouter();
const router = self._router;
var router = self._router;
// Mark all middleware added by Router ctor as builtin
// The sorting algo will keep them at beginning of the list
@ -261,14 +258,14 @@ proto.lazyrouter = function() {
router.__expressUse = router.use;
router.use = function useAndSort() {
const retval = this.__expressUse.apply(this, arguments);
var retval = this.__expressUse.apply(this, arguments);
self._sortLayersByPhase();
return retval;
};
router.__expressRoute = router.route;
router.route = function routeAndSort() {
const retval = this.__expressRoute.apply(this, arguments);
var retval = this.__expressRoute.apply(this, arguments);
self._sortLayersByPhase();
return retval;
};
@ -282,19 +279,19 @@ proto.lazyrouter = function() {
proto._sortLayersByPhase = function() {
if (this._skipLayerSorting) return;
const phaseOrder = {};
var phaseOrder = {};
this._requestHandlingPhases.forEach(function(name, ix) {
phaseOrder[name + ':before'] = ix * 3;
phaseOrder[name] = ix * 3 + 1;
phaseOrder[name + ':after'] = ix * 3 + 2;
});
const router = this._router;
var router = this._router;
stableSortInPlace(router.stack, compareLayers);
function compareLayers(left, right) {
const leftPhase = left.phase;
const rightPhase = right.phase;
var leftPhase = left.phase;
var rightPhase = right.phase;
if (leftPhase === rightPhase) return 0;

View File

@ -1,4 +1,4 @@
// Copyright IBM Corp. 2015,2019. All Rights Reserved.
// Copyright IBM Corp. 2015,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
@ -10,12 +10,12 @@ exports.uploadInChunks = uploadInChunks;
exports.downloadInChunks = downloadInChunks;
exports.concatResults = concatResults;
const Promise = require('bluebird');
const async = require('async');
var Promise = require('bluebird');
var async = require('async');
function createPromiseCallback() {
let cb;
const promise = new Promise(function(resolve, reject) {
var cb;
var promise = new Promise(function(resolve, reject) {
cb = function(err, data) {
if (err) return reject(err);
return resolve(data);
@ -28,7 +28,7 @@ function createPromiseCallback() {
function throwPromiseNotDefined() {
throw new Error(
'Your Node runtime does support ES6 Promises. ' +
'Set "global.Promise" to your preferred implementation of promises.',
'Set "global.Promise" to your preferred implementation of promises.'
);
}
@ -40,23 +40,23 @@ function throwPromiseNotDefined() {
* @param {Function} cb - the callback
*/
function uploadInChunks(largeArray, chunkSize, processFunction, cb) {
const chunkArrays = [];
var chunkArrays = [];
if (!chunkSize || chunkSize < 1 || largeArray.length <= chunkSize) {
// if chunking not required
processFunction(largeArray, cb);
} else {
// copying so that the largeArray object does not get affected during splice
const copyOfLargeArray = [].concat(largeArray);
var copyOfLargeArray = [].concat(largeArray);
// chunking to smaller arrays
while (copyOfLargeArray.length > 0) {
chunkArrays.push(copyOfLargeArray.splice(0, chunkSize));
}
const tasks = chunkArrays.map(function(chunkArray) {
var tasks = chunkArrays.map(function(chunkArray) {
return function(previousResults, chunkCallback) {
const lastArg = arguments[arguments.length - 1];
var lastArg = arguments[arguments.length - 1];
if (typeof lastArg === 'function') {
chunkCallback = lastArg;
@ -92,7 +92,7 @@ function uploadInChunks(largeArray, chunkSize, processFunction, cb) {
* @param {Function} cb - the callback
*/
function downloadInChunks(filter, chunkSize, processFunction, cb) {
let results = [];
var results = [];
filter = filter ? JSON.parse(JSON.stringify(filter)) : {};
if (!chunkSize || chunkSize < 1) {

View File

@ -1,6 +1,6 @@
{
"name": "loopback",
"version": "3.28.0",
"version": "3.22.2",
"description": "LoopBack: Open Source Framework for Node.js",
"homepage": "http://loopback.io",
"keywords": [
@ -34,7 +34,7 @@
"test": "nyc grunt mocha-and-karma"
},
"engines": {
"node": ">=8"
"node": ">=6"
},
"dependencies": {
"async": "^2.0.1",
@ -47,12 +47,12 @@
"ejs": "^2.3.1",
"express": "^4.14.0",
"inflection": "^1.6.0",
"isemail": "^3.2.0",
"isemail": "^2.2.1",
"loopback-connector-remote": "^3.0.0",
"loopback-datasource-juggler": "^3.28.0",
"loopback-datasource-juggler": "^3.18.0",
"loopback-filters": "^1.0.0",
"loopback-phase": "^3.0.0",
"nodemailer": "^6.4.16",
"nodemailer": "^4.0.1",
"nodemailer-direct-transport": "^3.3.2",
"nodemailer-stub-transport": "^1.1.0",
"serve-favicon": "^2.2.0",
@ -60,45 +60,48 @@
"strong-globalize": "^4.1.1",
"strong-remoting": "^3.11.0",
"uid2": "0.0.3",
"underscore.string": "^3.3.5"
"underscore.string": "^3.0.3"
},
"devDependencies": {
"browserify": "^16.5.0",
"chai": "^4.2.0",
"babel-preset-es2015": "^6.22.0",
"babelify": "^7.3.0",
"browserify": "^13.1.0",
"chai": "^3.5.0",
"cookie-parser": "^1.3.4",
"coveralls": "^3.0.2",
"dirty-chai": "^2.0.1",
"eslint": "^6.5.1",
"eslint-config-loopback": "^13.1.0",
"dirty-chai": "^1.2.2",
"eslint": "^5.3.0",
"eslint-config-loopback": "^11.0.0",
"eslint-plugin-mocha": "^5.1.0",
"express-session": "^1.14.0",
"grunt": "^1.0.1",
"grunt-browserify": "^5.0.0",
"grunt-cli": "^1.2.0",
"grunt-contrib-uglify": "^4.0.1",
"grunt-contrib-uglify": "^3.4.0",
"grunt-contrib-watch": "^1.0.0",
"grunt-eslint": "^22.0.0",
"grunt-karma": "^3.0.2",
"grunt-eslint": "^21.0.0",
"grunt-karma": "^2.0.0",
"grunt-mocha-test": "^0.13.3",
"is-docker": "^2.0.0",
"karma": "^4.1.0",
"karma-browserify": "^6.0.0",
"karma-chrome-launcher": "^3.1.0",
"karma": "^1.1.2",
"karma-browserify": "^5.1.1",
"karma-chrome-launcher": "^1.0.1",
"karma-es6-shim": "^1.0.0",
"karma-firefox-launcher": "^1.0.0",
"karma-html2js-preprocessor": "^1.0.0",
"karma-junit-reporter": "^1.2.0",
"karma-junit-reporter": "~1.0.0",
"karma-mocha": "^1.1.1",
"karma-phantomjs-launcher": "^1.0.0",
"karma-script-launcher": "^1.0.0",
"loopback-boot": "^2.7.0",
"loopback-context": "^1.0.0",
"mocha": "^6.2.1",
"nyc": "^14.1.1",
"sinon": "^7.5.0",
"mocha": "^5.2.0",
"nyc": "^10.1.2",
"phantomjs-prebuilt": "^2.1.7",
"sinon": "^6.1.4",
"sinon-chai": "^3.2.0",
"strong-error-handler": "^3.0.0",
"strong-task-emitter": "^0.0.8",
"supertest": "^4.0.2",
"which": "^2.0.1"
"supertest": "^3.0.0"
},
"repository": {
"type": "git",
@ -119,13 +122,5 @@
}
},
"copyright.owner": "IBM Corp.",
"license": "MIT",
"author": "IBM Corp.",
"ci": {
"downstreamIgnoreList": [
"bluemix-service-broker",
"gateway-director-bluemix",
"plan-manager"
]
}
"license": "MIT"
}

View File

@ -1,15 +1,15 @@
// Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Copyright IBM Corp. 2014,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const g = require('../../lib/globalize');
var g = require('../../lib/globalize');
module.exports = function() {
throw new Error(g.f(
'%s middleware was removed in version 3.0. See %s for more details.',
'loopback#context',
'http://loopback.io/doc/en/lb2/Using-current-context.html',
'http://loopback.io/doc/en/lb2/Using-current-context.html'
));
};

View File

@ -1,11 +1,11 @@
// Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Copyright IBM Corp. 2014,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const favicon = require('serve-favicon');
const path = require('path');
var favicon = require('serve-favicon');
var path = require('path');
/**
* Serve the LoopBack favicon.

View File

@ -1,4 +1,4 @@
// Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Copyright IBM Corp. 2014,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
@ -8,9 +8,9 @@
*/
'use strict';
const g = require('../../lib/globalize');
const loopback = require('../../lib/loopback');
const async = require('async');
var g = require('../../lib/globalize');
var loopback = require('../../lib/loopback');
var async = require('async');
/*!
* Export the middleware.
@ -30,27 +30,27 @@ module.exports = rest;
*/
function rest() {
let handlers; // Cached handlers
var handlers; // Cached handlers
return function restApiHandler(req, res, next) {
const app = req.app;
const registry = app.registry;
var app = req.app;
var registry = app.registry;
if (!handlers) {
handlers = [];
const remotingOptions = app.get('remoting') || {};
var remotingOptions = app.get('remoting') || {};
const contextOptions = remotingOptions.context;
var contextOptions = remotingOptions.context;
if (contextOptions !== undefined && contextOptions !== false) {
throw new Error(g.f(
'%s was removed in version 3.0. See %s for more details.',
'remoting.context option',
'http://loopback.io/doc/en/lb2/Using-current-context.html',
'http://loopback.io/doc/en/lb2/Using-current-context.html'
));
}
if (app.isAuthEnabled) {
const AccessToken = registry.getModelByType('AccessToken');
var AccessToken = registry.getModelByType('AccessToken');
handlers.push(loopback.token({model: AccessToken, app: app}));
}

View File

@ -1,4 +1,4 @@
// Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Copyright IBM Corp. 2014,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
@ -24,7 +24,7 @@ module.exports = status;
* @header loopback.status()
*/
function status() {
const started = new Date();
var started = new Date();
return function(req, res) {
res.send({

View File

@ -1,4 +1,4 @@
// Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Copyright IBM Corp. 2014,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
@ -8,10 +8,10 @@
*/
'use strict';
const g = require('../../lib/globalize');
const loopback = require('../../lib/loopback');
const assert = require('assert');
const debug = require('debug')('loopback:middleware:token');
var g = require('../../lib/globalize');
var loopback = require('../../lib/loopback');
var assert = require('assert');
var debug = require('debug')('loopback:middleware:token');
/*!
* Export the middleware.
@ -28,7 +28,7 @@ function rewriteUserLiteral(req, currentUserLiteral, next) {
if (req.accessToken && req.accessToken.userId) {
// Replace /me/ with /current-user-id/
const urlBeforeRewrite = req.url;
var urlBeforeRewrite = req.url;
req.url = req.url.replace(literalRegExp,
'/' + req.accessToken.userId + '$1');
@ -40,10 +40,10 @@ function rewriteUserLiteral(req, currentUserLiteral, next) {
debug(
'URL %s matches current-user literal %s,' +
' but no (valid) access token was provided.',
req.url, currentUserLiteral,
req.url, currentUserLiteral
);
const e = new Error(g.f('Authorization Required'));
var e = new Error(g.f('Authorization Required'));
e.status = e.statusCode = 401;
e.code = 'AUTHORIZATION_REQUIRED';
return next(e);
@ -97,9 +97,9 @@ function escapeRegExp(str) {
function token(options) {
options = options || {};
let TokenModel;
var TokenModel;
let currentUserLiteral = options.currentUserLiteral;
var currentUserLiteral = options.currentUserLiteral;
if (currentUserLiteral && (typeof currentUserLiteral !== 'string')) {
debug('Set currentUserLiteral to \'me\' as the value is not a string.');
currentUserLiteral = 'me';
@ -111,12 +111,12 @@ function token(options) {
if (options.bearerTokenBase64Encoded === undefined) {
options.bearerTokenBase64Encoded = true;
}
const enableDoublecheck = !!options.enableDoublecheck;
const overwriteExistingToken = !!options.overwriteExistingToken;
var enableDoublecheck = !!options.enableDoublecheck;
var overwriteExistingToken = !!options.overwriteExistingToken;
return function(req, res, next) {
const app = req.app;
const registry = app.registry;
var app = req.app;
var registry = app.registry;
if (!TokenModel) {
TokenModel = registry.getModel(options.model || 'AccessToken');
}
@ -141,7 +141,7 @@ function token(options) {
TokenModel.findForRequest(req, options, function(err, token) {
req.accessToken = token || null;
const ctx = req.loopbackContext;
var ctx = req.loopbackContext;
if (ctx && ctx.active) ctx.set('accessToken', token);
if (err) return next(err);

View File

@ -1,4 +1,4 @@
// Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Copyright IBM Corp. 2014,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
@ -18,7 +18,7 @@ module.exports = urlNotFound;
*/
function urlNotFound() {
return function raiseUrlNotFoundError(req, res, next) {
const error = new Error('Cannot ' + req.method + ' ' + req.url);
var error = new Error('Cannot ' + req.method + ' ' + req.url);
error.status = 404;
next(error);
};

View File

@ -1,18 +1,18 @@
// Copyright IBM Corp. 2013,2019. All Rights Reserved.
// Copyright IBM Corp. 2013,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const loopback = require('../');
const lt = require('./helpers/loopback-testing-helper');
const path = require('path');
const ACCESS_CONTROL_APP = path.join(__dirname, 'fixtures', 'access-control');
const app = require(path.join(ACCESS_CONTROL_APP, 'server/server.js'));
const assert = require('assert');
const USER = {email: 'test@test.test', password: 'test'};
const CURRENT_USER = {email: 'current@test.test', password: 'test'};
const debug = require('debug')('loopback:test:access-control.integration');
var loopback = require('../');
var lt = require('./helpers/loopback-testing-helper');
var path = require('path');
var ACCESS_CONTROL_APP = path.join(__dirname, 'fixtures', 'access-control');
var app = require(path.join(ACCESS_CONTROL_APP, 'server/server.js'));
var assert = require('assert');
var USER = {email: 'test@test.test', password: 'test'};
var CURRENT_USER = {email: 'current@test.test', password: 'test'};
var debug = require('debug')('loopback:test:access-control.integration');
describe('access control - integration', function() {
lt.beforeEach.withApp(app);
@ -75,11 +75,11 @@ describe('access control - integration', function() {
lt.it.shouldBeDeniedWhenCalledByUser(CURRENT_USER, 'GET', urlForUser);
lt.it.shouldBeAllowedWhenCalledAnonymously(
'POST', '/api/users', newUserData(),
'POST', '/api/users', newUserData()
);
lt.it.shouldBeAllowedWhenCalledByUser(
CURRENT_USER, 'POST', '/api/users', newUserData(),
CURRENT_USER, 'POST', '/api/users', newUserData()
);
lt.it.shouldBeAllowedWhenCalledByUser(CURRENT_USER, 'POST', '/api/users/logout');
@ -110,7 +110,7 @@ describe('access control - integration', function() {
this.res.statusCode,
this.res.headers,
this.res.text);
const user = this.res.body;
var user = this.res.body;
assert.equal(user.password, undefined);
});
});
@ -137,7 +137,7 @@ describe('access control - integration', function() {
return '/api/users/' + this.randomUser.id;
}
var userCounter; // eslint-disable-line no-var
var userCounter;
function newUserData() {
userCounter = userCounter ? ++userCounter : 1;
@ -149,14 +149,14 @@ describe('access control - integration', function() {
});
describe('/banks', function() {
const SPECIAL_USER = {email: 'special@test.test', password: 'test'};
var SPECIAL_USER = {email: 'special@test.test', password: 'test'};
// define dynamic role that would only grant access when the authenticated user's email is equal to
// SPECIAL_USER's email
before(function() {
const roleModel = app.registry.getModel('Role');
const userModel = app.registry.getModel('user');
var roleModel = app.registry.getModel('Role');
var userModel = app.registry.getModel('user');
roleModel.registerResolver('$dynamic-role', function(role, context, callback) {
if (!(context && context.accessToken && context.accessToken.userId)) {
@ -164,7 +164,7 @@ describe('access control - integration', function() {
if (callback) callback(null, false);
});
}
const accessToken = context.accessToken;
var accessToken = context.accessToken;
userModel.findById(accessToken.userId, function(err, user) {
if (err) {
return callback(err, false);
@ -210,9 +210,9 @@ describe('access control - integration', function() {
});
describe('/accounts with replaceOnPUT true', function() {
let count = 0;
var count = 0;
before(function() {
const roleModel = loopback.getModelByType(loopback.Role);
var roleModel = loopback.getModelByType(loopback.Role);
roleModel.registerResolver('$dummy', function(role, context, callback) {
process.nextTick(function() {
if (context.remotingContext) {
@ -250,9 +250,9 @@ describe('access control - integration', function() {
lt.it.shouldBeDeniedWhenCalledByUser(CURRENT_USER, 'PATCH', urlForAccount);
lt.describe.whenLoggedInAsUser(CURRENT_USER, function() {
let actId;
var actId;
beforeEach(function(done) {
const self = this;
var self = this;
// Create an account under the given user
app.models.accountWithReplaceOnPUTtrue.create({
userId: self.user.id,
@ -314,9 +314,9 @@ describe('access control - integration', function() {
lt.it.shouldBeDeniedWhenCalledByUser(CURRENT_USER, 'PATCH', urlForAccount);
lt.describe.whenLoggedInAsUser(CURRENT_USER, function() {
let actId;
var actId;
beforeEach(function(done) {
const self = this;
var self = this;
// Create an account under the given user
app.models.accountWithReplaceOnPUTfalse.create({
userId: self.user.id,

View File

@ -1,23 +1,23 @@
// Copyright IBM Corp. 2013,2019. All Rights Reserved.
// Copyright IBM Corp. 2013,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const assert = require('assert');
const expect = require('./helpers/expect');
const cookieParser = require('cookie-parser');
const LoopBackContext = require('loopback-context');
const contextMiddleware = require('loopback-context').perRequest;
const loopback = require('../');
const extend = require('util')._extend;
const session = require('express-session');
const request = require('supertest');
var assert = require('assert');
var expect = require('./helpers/expect');
var cookieParser = require('cookie-parser');
var LoopBackContext = require('loopback-context');
var contextMiddleware = require('loopback-context').perRequest;
var loopback = require('../');
var extend = require('util')._extend;
var session = require('express-session');
var request = require('supertest');
let Token, ACL, User, TestModel;
var Token, ACL, User, TestModel;
describe('loopback.token(options)', function() {
let app;
var app;
beforeEach(function(done) {
app = loopback({localRegistry: true, loadBuiltinModels: true});
app.dataSource('db', {connector: 'memory'});
@ -52,7 +52,7 @@ describe('loopback.token(options)', function() {
});
it('defaults to built-in AccessToken model', function() {
const BuiltInToken = app.registry.getModel('AccessToken');
var BuiltInToken = app.registry.getModel('AccessToken');
app.model(BuiltInToken, {dataSource: 'db'});
app.enableAuth({dataSource: 'db'});
@ -140,13 +140,13 @@ describe('loopback.token(options)', function() {
it('does not search default keys when searchDefaultTokenKeys is false',
function(done) {
const tokenId = this.token.id;
const app = createTestApp(
var tokenId = this.token.id;
var app = createTestApp(
this.token,
{token: {searchDefaultTokenKeys: false}},
done,
done
);
const agent = request.agent(app);
var agent = request.agent(app);
// Set the token cookie
agent.get('/token').expect(200).end(function(err, res) {
@ -165,7 +165,7 @@ describe('loopback.token(options)', function() {
it('populates req.token from an authorization header with bearer token with base64',
function(done) {
let token = this.token.id;
var token = this.token.id;
token = 'Bearer ' + new Buffer(token).toString('base64');
createTestAppAndRequest(this.token, done)
.get('/')
@ -175,7 +175,7 @@ describe('loopback.token(options)', function() {
});
it('populates req.token from an authorization header with bearer token', function(done) {
let token = this.token.id;
var token = this.token.id;
token = 'Bearer ' + token;
createTestAppAndRequest(this.token, {token: {bearerTokenBase64Encoded: false}}, done)
.get('/')
@ -186,7 +186,7 @@ describe('loopback.token(options)', function() {
describe('populating req.token from HTTP Basic Auth formatted authorization header', function() {
it('parses "standalone-token"', function(done) {
let token = this.token.id;
var token = this.token.id;
token = 'Basic ' + new Buffer(token).toString('base64');
createTestAppAndRequest(this.token, done)
.get('/')
@ -196,7 +196,7 @@ describe('loopback.token(options)', function() {
});
it('parses "token-and-empty-password:"', function(done) {
let token = this.token.id + ':';
var token = this.token.id + ':';
token = 'Basic ' + new Buffer(token).toString('base64');
createTestAppAndRequest(this.token, done)
.get('/')
@ -206,7 +206,7 @@ describe('loopback.token(options)', function() {
});
it('parses "ignored-user:token-is-password"', function(done) {
let token = 'username:' + this.token.id;
var token = 'username:' + this.token.id;
token = 'Basic ' + new Buffer(token).toString('base64');
createTestAppAndRequest(this.token, done)
.get('/')
@ -216,7 +216,7 @@ describe('loopback.token(options)', function() {
});
it('parses "token-is-username:ignored-password"', function(done) {
let token = this.token.id + ':password';
var token = this.token.id + ':password';
token = 'Basic ' + new Buffer(token).toString('base64');
createTestAppAndRequest(this.token, done)
.get('/')
@ -227,7 +227,7 @@ describe('loopback.token(options)', function() {
});
it('populates req.token from a secure cookie', function(done) {
const app = createTestApp(this.token, done);
var app = createTestApp(this.token, done);
request(app)
.get('/token')
@ -240,8 +240,8 @@ describe('loopback.token(options)', function() {
});
it('populates req.token from a header or a secure cookie', function(done) {
const app = createTestApp(this.token, done);
const id = this.token.id;
var app = createTestApp(this.token, done);
var id = this.token.id;
request(app)
.get('/token')
.end(function(err, res) {
@ -255,9 +255,9 @@ describe('loopback.token(options)', function() {
it('rewrites url for the current user literal at the end without query',
function(done) {
const app = createTestApp(this.token, done);
const id = this.token.id;
const userId = this.token.userId;
var app = createTestApp(this.token, done);
var id = this.token.id;
var userId = this.token.userId;
request(app)
.get('/users/me')
.set('authorization', id)
@ -271,9 +271,9 @@ describe('loopback.token(options)', function() {
it('rewrites url for the current user literal at the end with query',
function(done) {
const app = createTestApp(this.token, done);
const id = this.token.id;
const userId = this.token.userId;
var app = createTestApp(this.token, done);
var id = this.token.id;
var userId = this.token.userId;
request(app)
.get('/users/me?state=1')
.set('authorization', id)
@ -287,9 +287,9 @@ describe('loopback.token(options)', function() {
it('rewrites url for the current user literal in the middle',
function(done) {
const app = createTestApp(this.token, done);
const id = this.token.id;
const userId = this.token.userId;
var app = createTestApp(this.token, done);
var id = this.token.id;
var userId = this.token.userId;
request(app)
.get('/users/me/1')
.set('authorization', id)
@ -303,7 +303,7 @@ describe('loopback.token(options)', function() {
it('generates a 401 on a current user literal route without an authToken',
function(done) {
const app = createTestApp(null, done);
var app = createTestApp(null, done);
request(app)
.get('/users/me')
.set('authorization', null)
@ -311,19 +311,9 @@ describe('loopback.token(options)', function() {
.end(done);
});
it('generates a 401 on a current user literal route with empty authToken',
function(done) {
const app = createTestApp(null, done);
request(app)
.get('/users/me')
.set('authorization', '')
.expect(401)
.end(done);
});
it('generates a 401 on a current user literal route with invalid authToken',
function(done) {
const app = createTestApp(this.token, done);
var app = createTestApp(this.token, done);
request(app)
.get('/users/me')
.set('Authorization', 'invald-token-id')
@ -332,7 +322,7 @@ describe('loopback.token(options)', function() {
});
it('skips when req.token is already present', function(done) {
const tokenStub = {id: 'stub id'};
var tokenStub = {id: 'stub id'};
app.use(function(req, res, next) {
req.accessToken = tokenStub;
@ -358,7 +348,7 @@ describe('loopback.token(options)', function() {
describe('loading multiple instances of token middleware', function() {
it('skips when req.token is already present and no further options are set',
function(done) {
const tokenStub = {id: 'stub id'};
var tokenStub = {id: 'stub id'};
app.use(function(req, res, next) {
req.accessToken = tokenStub;
@ -384,7 +374,7 @@ describe('loopback.token(options)', function() {
it('does not overwrite valid existing token (has "id" property) ' +
' when overwriteExistingToken is falsy',
function(done) {
const tokenStub = {id: 'stub id'};
var tokenStub = {id: 'stub id'};
app.use(function(req, res, next) {
req.accessToken = tokenStub;
@ -413,7 +403,7 @@ describe('loopback.token(options)', function() {
it('overwrites invalid existing token (is !== undefined and has no "id" property) ' +
' when enableDoublecheck is true',
function(done) {
const token = this.token;
var token = this.token;
app.use(function(req, res, next) {
req.accessToken = null;
next();
@ -446,8 +436,8 @@ describe('loopback.token(options)', function() {
it('overwrites existing token when enableDoublecheck ' +
'and overwriteExistingToken options are truthy',
function(done) {
const token = this.token;
const tokenStub = {id: 'stub id'};
var token = this.token;
var tokenStub = {id: 'stub id'};
app.use(function(req, res, next) {
req.accessToken = tokenStub;
@ -521,7 +511,7 @@ describe('AccessToken', function() {
it('allows eternal tokens when enabled by User.allowEternalTokens',
function(done) {
const Token = givenLocalTokenModel();
var Token = givenLocalTokenModel();
// Overwrite User settings - enable eternal tokens
Token.app.models.User.settings.allowEternalTokens = true;
@ -541,8 +531,8 @@ describe('AccessToken', function() {
beforeEach(createTestingToken);
it('supports two-arg variant with no options', function(done) {
const expectedTokenId = this.token.id;
const req = mockRequest({
var expectedTokenId = this.token.id;
var req = mockRequest({
headers: {'authorization': expectedTokenId},
});
@ -556,14 +546,14 @@ describe('AccessToken', function() {
});
it('allows getIdForRequest() to be overridden', function(done) {
const expectedTokenId = this.token.id;
const current = Token.getIdForRequest;
let called = false;
var expectedTokenId = this.token.id;
var current = Token.getIdForRequest;
var called = false;
Token.getIdForRequest = function(req, options) {
called = true;
return expectedTokenId;
};
const req = mockRequest({
var req = mockRequest({
headers: {'authorization': 'dummy'},
});
@ -579,16 +569,16 @@ describe('AccessToken', function() {
});
it('allows resolve() to be overridden', function(done) {
const expectedTokenId = this.token.id;
const current = Token.resolve;
let called = false;
var expectedTokenId = this.token.id;
var current = Token.resolve;
var called = false;
Token.resolve = function(id, cb) {
called = true;
process.nextTick(function() {
cb(null, {id: expectedTokenId});
});
};
const req = mockRequest({
var req = mockRequest({
headers: {'authorization': expectedTokenId},
});
@ -615,14 +605,14 @@ describe('AccessToken', function() {
param: function(name) { return this._params[name]; },
header: function(name) { return this.headers[name]; },
},
opts,
opts
);
}
});
});
describe('app.enableAuth()', function() {
let app;
var app;
beforeEach(function setupAuthWithModels() {
app = loopback({localRegistry: true, loadBuiltinModels: true});
app.dataSource('db', {connector: 'memory'});
@ -653,7 +643,7 @@ describe('app.enableAuth()', function() {
return done(err);
}
const errorResponse = res.body.error;
var errorResponse = res.body.error;
assert(errorResponse);
assert.equal(errorResponse.code, 'AUTHORIZATION_REQUIRED');
@ -671,7 +661,7 @@ describe('app.enableAuth()', function() {
return done(err);
}
const errorResponse = res.body.error;
var errorResponse = res.body.error;
assert(errorResponse);
assert.equal(errorResponse.code, 'ACCESS_DENIED');
@ -689,7 +679,7 @@ describe('app.enableAuth()', function() {
return done(err);
}
const errorResponse = res.body.error;
var errorResponse = res.body.error;
assert(errorResponse);
assert.equal(errorResponse.code, 'MODEL_NOT_FOUND');
@ -707,7 +697,7 @@ describe('app.enableAuth()', function() {
return done(err);
}
const errorResponse = res.body.error;
var errorResponse = res.body.error;
assert(errorResponse);
assert.equal(errorResponse.code, 'AUTHORIZATION_REQUIRED');
@ -716,9 +706,9 @@ describe('app.enableAuth()', function() {
});
it('stores token in the context', function(done) {
const TestModel = app.registry.createModel('TestModel', {base: 'Model'});
var TestModel = app.registry.createModel('TestModel', {base: 'Model'});
TestModel.getToken = function(cb) {
const ctx = LoopBackContext.getCurrentContext();
var ctx = LoopBackContext.getCurrentContext();
cb(null, ctx && ctx.get('accessToken') || null);
};
TestModel.remoteMethod('getToken', {
@ -733,7 +723,7 @@ describe('app.enableAuth()', function() {
app.use(loopback.token({model: Token}));
app.use(loopback.rest());
const token = this.token;
var token = this.token;
request(app)
.get('/TestModels/token?_format=json')
.set('authorization', token.id)
@ -772,7 +762,7 @@ describe('app.enableAuth()', function() {
});
function createTestingToken(done) {
const test = this;
var test = this;
Token.create({userId: '123'}, function(err, token) {
if (err) return done(err);
@ -783,7 +773,7 @@ function createTestingToken(done) {
}
function createTestAppAndRequest(testToken, settings, done) {
const app = createTestApp(testToken, settings, done);
var app = createTestApp(testToken, settings, done);
return request(app);
}
@ -793,14 +783,14 @@ function createTestApp(testToken, settings, done) {
settings = {};
}
const appSettings = settings.app || {};
const modelSettings = settings.model || {};
const tokenSettings = extend({
var appSettings = settings.app || {};
var modelSettings = settings.model || {};
var tokenSettings = extend({
model: Token,
currentUserLiteral: 'me',
}, settings.token);
const app = loopback({localRegistry: true, loadBuiltinModels: true});
var app = loopback({localRegistry: true, loadBuiltinModels: true});
app.dataSource('db', {connector: 'memory'});
app.use(cookieParser('secret'));
@ -824,7 +814,7 @@ function createTestApp(testToken, settings, done) {
res.status(req.accessToken ? 200 : 401).end();
});
app.use('/users/:uid', function(req, res) {
const result = {userId: req.params.uid};
var result = {userId: req.params.uid};
if (req.query.state) {
result.state = req.query.state;
} else if (req.url !== '/') {
@ -839,7 +829,7 @@ function createTestApp(testToken, settings, done) {
app.set(key, appSettings[key]);
});
const modelOptions = {
var modelOptions = {
acls: [
{
principalType: 'ROLE',
@ -855,20 +845,20 @@ function createTestApp(testToken, settings, done) {
modelOptions[key] = modelSettings[key];
});
const TestModel = app.registry.createModel('test', {}, modelOptions);
var TestModel = app.registry.createModel('test', {}, modelOptions);
app.model(TestModel, {dataSource: 'db'});
return app;
}
function givenLocalTokenModel() {
const app = loopback({localRegistry: true, loadBuiltinModels: true});
var app = loopback({localRegistry: true, loadBuiltinModels: true});
app.dataSource('db', {connector: 'memory'});
const User = app.registry.getModel('User');
var User = app.registry.getModel('User');
app.model(User, {dataSource: 'db'});
const Token = app.registry.getModel('AccessToken');
var Token = app.registry.getModel('AccessToken');
app.model(Token, {dataSource: 'db'});
return Token;

View File

@ -1,27 +1,34 @@
// Copyright IBM Corp. 2013,2019. All Rights Reserved.
// Copyright IBM Corp. 2013,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const assert = require('assert');
const expect = require('./helpers/expect');
const loopback = require('../index');
const Scope = loopback.Scope;
const ACL = loopback.ACL;
const request = require('supertest');
const Promise = require('bluebird');
const supertest = require('supertest');
const Role = loopback.Role;
const RoleMapping = loopback.RoleMapping;
const User = loopback.User;
const async = require('async');
var assert = require('assert');
var expect = require('./helpers/expect');
var loopback = require('../index');
var Scope = loopback.Scope;
var ACL = loopback.ACL;
var request = require('supertest');
var Promise = require('bluebird');
var supertest = require('supertest');
var Role = loopback.Role;
var RoleMapping = loopback.RoleMapping;
var User = loopback.User;
var testModel;
// Speed up the password hashing algorithm for tests
User.settings.saltWorkFactor = 4;
let ds = null;
let testModel;
function checkResult(err, result) {
// console.log(err, result);
assert(!err);
}
var ds = null;
before(function() {
ds = loopback.createDataSource({connector: loopback.Memory});
});
describe('ACL model', function() {
it('provides DEFAULT_SCOPE constant', () => {
@ -30,9 +37,18 @@ describe('ACL model', function() {
});
describe('security scopes', function() {
beforeEach(setupTestModels);
beforeEach(function() {
var ds = this.ds = loopback.createDataSource({connector: loopback.Memory});
testModel = loopback.PersistedModel.extend('testModel');
ACL.attachTo(ds);
Role.attachTo(ds);
RoleMapping.attachTo(ds);
User.attachTo(ds);
Scope.attachTo(ds);
testModel.attachTo(ds);
});
it('should allow access to models for the given scope by wildcard', function(done) {
it('should allow access to models for the given scope by wildcard', function() {
Scope.create({name: 'userScope', description: 'access user information'},
function(err, scope) {
ACL.create({
@ -40,19 +56,14 @@ describe('security scopes', function() {
model: 'User', property: ACL.ALL,
accessType: ACL.ALL, permission: ACL.ALLOW,
}, function(err, resource) {
async.parallel([
cb => Scope.checkPermission('userScope', 'User', ACL.ALL, ACL.ALL, cb),
cb => Scope.checkPermission('userScope', 'User', 'name', ACL.ALL, cb),
cb => Scope.checkPermission('userScope', 'User', 'name', ACL.READ, cb),
], (err) => {
assert.ifError(err);
done();
});
Scope.checkPermission('userScope', 'User', ACL.ALL, ACL.ALL, checkResult);
Scope.checkPermission('userScope', 'User', 'name', ACL.ALL, checkResult);
Scope.checkPermission('userScope', 'User', 'name', ACL.READ, checkResult);
});
});
});
it('should allow access to models for the given scope', function(done) {
it('should allow access to models for the given scope', function() {
Scope.create({name: 'testModelScope', description: 'access testModel information'},
function(err, scope) {
ACL.create({
@ -64,21 +75,23 @@ describe('security scopes', function() {
model: 'testModel', property: 'name',
accessType: ACL.WRITE, permission: ACL.DENY,
}, function(err, resource) {
async.parallel([
cb => Scope.checkPermission('testModelScope', 'testModel', ACL.ALL, ACL.ALL, cb),
cb => Scope.checkPermission('testModelScope', 'testModel', 'name', ACL.ALL, cb),
cb => Scope.checkPermission('testModelScope', 'testModel', 'name', ACL.READ, cb),
cb => Scope.checkPermission('testModelScope', 'testModel', 'name', ACL.WRITE, cb),
], (err, perms) => {
if (err) return done(err);
assert.deepEqual(perms.map(p => p.permission), [
ACL.DENY,
ACL.DENY,
ACL.ALLOW,
ACL.DENY,
]);
done();
});
// console.log(resource);
Scope.checkPermission('testModelScope', 'testModel', ACL.ALL, ACL.ALL,
function(err, perm) {
assert(perm.permission === ACL.DENY); // because name.WRITE == DENY
});
Scope.checkPermission('testModelScope', 'testModel', 'name', ACL.ALL,
function(err, perm) {
assert(perm.permission === ACL.DENY); // because name.WRITE == DENY
});
Scope.checkPermission('testModelScope', 'testModel', 'name', ACL.READ,
function(err, perm) {
assert(perm.permission === ACL.ALLOW);
});
Scope.checkPermission('testModelScope', 'testModel', 'name', ACL.WRITE,
function(err, perm) {
assert(perm.permission === ACL.DENY);
});
});
});
});
@ -86,8 +99,6 @@ describe('security scopes', function() {
});
describe('security ACLs', function() {
beforeEach(setupTestModels);
it('supports checkPermission() returning a promise', function() {
return ACL.create({
principalType: ACL.USER,
@ -105,46 +116,8 @@ describe('security ACLs', function() {
});
});
it('supports ACL rules with a wildcard for models', function() {
const A_USER_ID = 'a-test-user';
// By default, access is allowed to all users
return assertPermission(ACL.ALLOW, 'initial state')
// An ACL rule applying to all models denies access to everybody
.then(() => ACL.create({
model: '*',
property: '*',
accessType: '*',
principalType: 'ROLE',
principalId: '$everyone',
permission: 'DENY',
}))
.then(() => assertPermission(ACL.DENY, 'all denied'))
// A rule for a specific model overrides the rule matching all models
.then(() => ACL.create({
model: testModel.modelName,
property: '*',
accessType: '*',
principalType: ACL.USER,
principalId: A_USER_ID,
permission: ACL.ALLOW,
}))
.then(() => assertPermission(ACL.ALLOW, 'only a single model allowed'));
function assertPermission(expectedPermission, msg) {
return ACL.checkAccessForContext({
principals: [{type: ACL.USER, id: A_USER_ID}],
model: testModel.modelName,
accessType: ACL.ALL,
}).then(accessContext => {
const actual = accessContext.isAllowed() ? ACL.ALLOW : ACL.DENY;
expect(actual, msg).to.equal(expectedPermission);
});
}
});
it('supports checkAccessForContext() returning a promise', function() {
const testModel = ds.createModel('testModel', {
var testModel = ds.createModel('testModel', {
acls: [
{principalType: ACL.USER, principalId: 'u001',
accessType: ACL.ALL, permission: ACL.ALLOW},
@ -162,7 +135,7 @@ describe('security ACLs', function() {
});
it('should order ACL entries based on the matching score', function() {
let acls = [
var acls = [
{
'model': 'account',
'accessType': '*',
@ -184,7 +157,7 @@ describe('security ACLs', function() {
'principalType': 'ROLE',
'principalId': '$everyone',
}];
const req = {
var req = {
model: 'account',
property: 'find',
accessType: 'WRITE',
@ -192,7 +165,7 @@ describe('security ACLs', function() {
acls = acls.map(function(a) { return new ACL(a); });
const perm = ACL.resolvePermission(acls, req);
var perm = ACL.resolvePermission(acls, req);
// remove the registry from AccessRequest instance to ease asserting
delete perm.registry;
assert.deepEqual(perm, {model: 'account',
@ -214,7 +187,7 @@ describe('security ACLs', function() {
});
it('should order ACL entries based on the matching score even with wildcard req', function() {
let acls = [
var acls = [
{
'model': 'account',
'accessType': '*',
@ -229,7 +202,7 @@ describe('security ACLs', function() {
'principalType': 'ROLE',
'principalId': '$owner',
}];
const req = {
var req = {
model: 'account',
property: '*',
accessType: 'WRITE',
@ -237,7 +210,7 @@ describe('security ACLs', function() {
acls = acls.map(function(a) { return new ACL(a); });
const perm = ACL.resolvePermission(acls, req);
var perm = ACL.resolvePermission(acls, req);
// remove the registry from AccessRequest instance to ease asserting.
// Check the above test case for more info.
delete perm.registry;
@ -248,7 +221,7 @@ describe('security ACLs', function() {
methodNames: []});
});
it('should allow access to models for the given principal by wildcard', function(done) {
it('should allow access to models for the given principal by wildcard', function() {
// jscs:disable validateIndentation
ACL.create({
principalType: ACL.USER, principalId: 'u001', model: 'User', property: ACL.ALL,
@ -258,22 +231,18 @@ describe('security ACLs', function() {
principalType: ACL.USER, principalId: 'u001', model: 'User', property: ACL.ALL,
accessType: ACL.READ, permission: ACL.DENY,
}, function(err, acl) {
async.parallel([
cb => ACL.checkPermission(ACL.USER, 'u001', 'User', 'name', ACL.READ, cb),
cb => ACL.checkPermission(ACL.USER, 'u001', 'User', 'name', ACL.ALL, cb),
], (err, perms) => {
if (err) return done(err);
assert.deepEqual(perms.map(p => p.permission), [
ACL.DENY,
ACL.DENY,
]);
done();
ACL.checkPermission(ACL.USER, 'u001', 'User', 'name', ACL.READ, function(err, perm) {
assert(perm.permission === ACL.DENY);
});
ACL.checkPermission(ACL.USER, 'u001', 'User', 'name', ACL.ALL, function(err, perm) {
assert(perm.permission === ACL.DENY);
});
});
});
});
it('should allow access to models by exception', function(done) {
it('should allow access to models by exception', function() {
ACL.create({
principalType: ACL.USER, principalId: 'u001', model: 'testModel', property: ACL.ALL,
accessType: ACL.ALL, permission: ACL.DENY,
@ -286,32 +255,42 @@ describe('security ACLs', function() {
principalType: ACL.USER, principalId: 'u002', model: 'testModel', property: ACL.ALL,
accessType: ACL.EXECUTE, permission: ACL.ALLOW,
}, function(err, acl) {
async.parallel([
cb => ACL.checkPermission(ACL.USER, 'u001', 'testModel', 'name', ACL.READ, cb),
cb => ACL.checkPermission(ACL.USER, 'u001', 'testModel', ACL.ALL, ACL.READ, cb),
cb => ACL.checkPermission(ACL.USER, 'u001', 'testModel', 'name', ACL.WRITE, cb),
cb => ACL.checkPermission(ACL.USER, 'u001', 'testModel', 'name', ACL.ALL, cb),
cb => ACL.checkPermission(ACL.USER, 'u002', 'testModel', 'name', ACL.WRITE, cb),
cb => ACL.checkPermission(ACL.USER, 'u002', 'testModel', 'name', ACL.READ, cb),
], (err, perms) => {
if (err) return done(err);
assert.deepEqual(perms.map(p => p.permission), [
ACL.ALLOW,
ACL.ALLOW,
ACL.DENY,
ACL.DENY,
ACL.ALLOW,
ACL.ALLOW,
]);
done();
});
ACL.checkPermission(ACL.USER, 'u001', 'testModel', 'name', ACL.READ,
function(err, perm) {
assert(perm.permission === ACL.ALLOW);
});
ACL.checkPermission(ACL.USER, 'u001', 'testModel', ACL.ALL, ACL.READ,
function(err, perm) {
assert(perm.permission === ACL.ALLOW);
});
ACL.checkPermission(ACL.USER, 'u001', 'testModel', 'name', ACL.WRITE,
function(err, perm) {
assert(perm.permission === ACL.DENY);
});
ACL.checkPermission(ACL.USER, 'u001', 'testModel', 'name', ACL.ALL,
function(err, perm) {
assert(perm.permission === ACL.DENY);
});
ACL.checkPermission(ACL.USER, 'u002', 'testModel', 'name', ACL.WRITE,
function(err, perm) {
assert(perm.permission === ACL.ALLOW);
});
ACL.checkPermission(ACL.USER, 'u002', 'testModel', 'name', ACL.READ,
function(err, perm) {
assert(perm.permission === ACL.ALLOW);
});
});
});
});
});
it('should honor defaultPermission from the model', function(done) {
const Customer = ds.createModel('Customer', {
it('should honor defaultPermission from the model', function() {
var Customer = ds.createModel('Customer', {
name: {
type: String,
acls: [
@ -331,23 +310,22 @@ describe('security ACLs', function() {
// ACL default permission is to DENY for model Customer
Customer.settings.defaultPermission = ACL.DENY;
async.parallel([
cb => ACL.checkPermission(ACL.USER, 'u001', 'Customer', 'name', ACL.WRITE, cb),
cb => ACL.checkPermission(ACL.USER, 'u001', 'Customer', 'name', ACL.READ, cb),
cb => ACL.checkPermission(ACL.USER, 'u002', 'Customer', 'name', ACL.WRITE, cb),
], (err, perms) => {
if (err) return done(err);
assert.deepEqual(perms.map(p => p.permission), [
ACL.DENY,
ACL.ALLOW,
ACL.DENY,
]);
done();
ACL.checkPermission(ACL.USER, 'u001', 'Customer', 'name', ACL.WRITE,
function(err, perm) {
assert(perm.permission === ACL.DENY);
});
ACL.checkPermission(ACL.USER, 'u001', 'Customer', 'name', ACL.READ, function(err, perm) {
assert(perm.permission === ACL.ALLOW);
});
ACL.checkPermission(ACL.USER, 'u002', 'Customer', 'name', ACL.WRITE, function(err, perm) {
assert(perm.permission === ACL.DENY);
});
});
it('should honor static ACLs from the model', function(done) {
const Customer = ds.createModel('Customer', {
it('should honor static ACLs from the model', function() {
var Customer = ds.createModel('Customer', {
name: {
type: String,
acls: [
@ -374,27 +352,34 @@ describe('security ACLs', function() {
];
*/
async.parallel([
cb => ACL.checkPermission(ACL.USER, 'u001', 'Customer', 'name', ACL.WRITE, cb),
cb => ACL.checkPermission(ACL.USER, 'u001', 'Customer', 'name', ACL.READ, cb),
cb => ACL.checkPermission(ACL.USER, 'u001', 'Customer', 'name', ACL.ALL, cb),
cb => ACL.checkPermission(ACL.USER, 'u002', 'Customer', 'name', ACL.READ, cb),
cb => ACL.checkPermission(ACL.USER, 'u003', 'Customer', 'name', ACL.WRITE, cb),
], (err, perms) => {
if (err) return done(err);
assert.deepEqual(perms.map(p => p.permission), [
ACL.DENY,
ACL.ALLOW,
ACL.ALLOW,
ACL.ALLOW,
ACL.DENY,
]);
done();
});
ACL.checkPermission(ACL.USER, 'u001', 'Customer', 'name', ACL.WRITE,
function(err, perm) {
assert(perm.permission === ACL.DENY);
});
ACL.checkPermission(ACL.USER, 'u001', 'Customer', 'name', ACL.READ,
function(err, perm) {
assert(perm.permission === ACL.ALLOW);
});
ACL.checkPermission(ACL.USER, 'u001', 'Customer', 'name', ACL.ALL,
function(err, perm) {
assert(perm.permission === ACL.ALLOW);
});
ACL.checkPermission(ACL.USER, 'u002', 'Customer', 'name', ACL.READ,
function(err, perm) {
assert(perm.permission === ACL.ALLOW);
});
ACL.checkPermission(ACL.USER, 'u003', 'Customer', 'name', ACL.WRITE,
function(err, perm) {
assert(perm.permission === ACL.DENY);
});
});
it('should filter static ACLs by model/property', function() {
const Model1 = ds.createModel('Model1', {
var Model1 = ds.createModel('Model1', {
name: {
type: String,
acls: [
@ -415,7 +400,7 @@ describe('security ACLs', function() {
],
});
let staticACLs = ACL.getStaticACLs('Model1', 'name');
var staticACLs = ACL.getStaticACLs('Model1', 'name');
assert(staticACLs.length === 3);
staticACLs = ACL.getStaticACLs('Model1', 'findOne');
@ -426,17 +411,18 @@ describe('security ACLs', function() {
assert(staticACLs[0].property === 'findById');
});
it('should check access against LDL, ACL, and Role', function(done) {
const log = function() {};
it('should check access against LDL, ACL, and Role', function() {
// var log = console.log;
var log = function() {};
// Create
User.create({name: 'Raymond', email: 'x@y.com', password: 'foobar'}, function(err, user) {
log('User: ', user.toObject());
const userId = user.id;
var userId = user.id;
// Define a model with static ACLs
const Customer = ds.createModel('Customer', {
var Customer = ds.createModel('Customer', {
name: {
type: String,
acls: [
@ -475,35 +461,27 @@ describe('security ACLs', function() {
}, function(err, acl) {
log('ACL 2: ', acl.toObject());
async.parallel([
cb => {
ACL.checkAccessForContext({
principals: [
{type: ACL.USER, id: userId},
],
model: 'Customer',
property: 'name',
accessType: ACL.READ,
}, function(err, access) {
assert.ifError(err);
assert.equal(access.permission, ACL.ALLOW);
cb();
});
},
cb => {
ACL.checkAccessForContext({
principals: [
{type: ACL.ROLE, id: Role.EVERYONE},
],
model: 'Customer',
property: 'name',
accessType: ACL.READ,
}, function(err, access) {
assert.ifError(err);
assert.equal(access.permission, ACL.DENY);
cb();
});
}], done);
ACL.checkAccessForContext({
principals: [
{type: ACL.USER, id: userId},
],
model: 'Customer',
property: 'name',
accessType: ACL.READ,
}, function(err, access) {
assert(!err && access.permission === ACL.ALLOW);
});
ACL.checkAccessForContext({
principals: [
{type: ACL.ROLE, id: Role.EVERYONE},
],
model: 'Customer',
property: 'name',
accessType: ACL.READ,
}, function(err, access) {
assert(!err && access.permission === ACL.DENY);
});
});
});
});
@ -514,10 +492,10 @@ describe('security ACLs', function() {
describe('access check', function() {
it('should occur before other remote hooks', function(done) {
const app = loopback();
const MyTestModel = app.registry.createModel('MyTestModel');
let checkAccessCalled = false;
let beforeHookCalled = false;
var app = loopback();
var MyTestModel = app.registry.createModel('MyTestModel');
var checkAccessCalled = false;
var beforeHookCalled = false;
app.use(loopback.rest());
app.set('remoting', {errorHandler: {debug: true, log: false}});
@ -527,9 +505,9 @@ describe('access check', function() {
// fake / spy on the checkAccess method
MyTestModel.checkAccess = function() {
const cb = arguments[arguments.length - 1];
var cb = arguments[arguments.length - 1];
checkAccessCalled = true;
const allowed = true;
var allowed = true;
cb(null, allowed);
};
@ -554,8 +532,8 @@ describe('access check', function() {
});
describe('authorized roles propagation in RemotingContext', function() {
let app, request, accessToken;
let models = {};
var app, request, accessToken;
var models = {};
beforeEach(setupAppAndRequest);
@ -567,13 +545,13 @@ describe('authorized roles propagation in RemotingContext', function() {
])
.then(makeAuthorizedHttpRequestOnMyTestModel)
.then(function() {
const ctx = models.MyTestModel.lastRemotingContext;
var ctx = models.MyTestModel.lastRemotingContext;
expect(ctx.args.options.authorizedRoles).to.eql(
{
$everyone: true,
$authenticated: true,
myRole: true,
},
}
);
});
});
@ -586,12 +564,12 @@ describe('authorized roles propagation in RemotingContext', function() {
])
.then(makeAuthorizedHttpRequestOnMyTestModel)
.then(function() {
const ctx = models.MyTestModel.lastRemotingContext;
var ctx = models.MyTestModel.lastRemotingContext;
expect(ctx.args.options.authorizedRoles).to.eql(
{
$everyone: true,
myRole: true,
},
}
);
});
});
@ -607,10 +585,10 @@ describe('authorized roles propagation in RemotingContext', function() {
])
.then(makeAuthorizedHttpRequestOnMyTestModel)
.then(function() {
const ctx = models.MyTestModel.lastRemotingContext;
var ctx = models.MyTestModel.lastRemotingContext;
expect(ctx.args.options.authorizedRoles).to.eql(
// '$everyone' is not expected as default permission is DENY
{myRole: true},
{myRole: true}
);
});
});
@ -626,9 +604,6 @@ describe('authorized roles propagation in RemotingContext', function() {
app.enableAuth({dataSource: 'db'});
models = app.models;
// Speed up the password hashing algorithm for tests
models.User.settings.saltWorkFactor = 4;
// creating a custom model
const MyTestModel = app.registry.createModel('MyTestModel');
app.model(MyTestModel, {dataSource: 'db'});
@ -667,7 +642,7 @@ describe('authorized roles propagation in RemotingContext', function() {
});
});
return Promise.all(acls);
}
};
function makeAuthorizedHttpRequestOnMyTestModel() {
return request.get('/MyTestModels')
@ -675,14 +650,3 @@ describe('authorized roles propagation in RemotingContext', function() {
.expect(200);
}
});
function setupTestModels() {
ds = this.ds = loopback.createDataSource({connector: loopback.Memory});
testModel = loopback.PersistedModel.extend('testModel');
ACL.attachTo(ds);
Role.attachTo(ds);
RoleMapping.attachTo(ds);
User.attachTo(ds);
Scope.attachTo(ds);
testModel.attachTo(ds);
}

View File

@ -1,39 +1,39 @@
// Copyright IBM Corp. 2013,2019. All Rights Reserved.
// Copyright IBM Corp. 2013,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const assert = require('assert');
const async = require('async');
const path = require('path');
var assert = require('assert');
var async = require('async');
var path = require('path');
const http = require('http');
const express = require('express');
const loopback = require('../');
const PersistedModel = loopback.PersistedModel;
var http = require('http');
var express = require('express');
var loopback = require('../');
var PersistedModel = loopback.PersistedModel;
const describe = require('./util/describe');
const expect = require('./helpers/expect');
const it = require('./util/it');
const request = require('supertest');
var describe = require('./util/describe');
var expect = require('./helpers/expect');
var it = require('./util/it');
var request = require('supertest');
const sinon = require('sinon');
describe('app', function() {
let app;
var app;
beforeEach(function() {
app = loopback({localRegistry: true, loadBuiltinModels: true});
});
describe.onServer('.middleware(phase, handler)', function() {
let steps;
var steps;
beforeEach(function setup() {
steps = [];
});
it('runs middleware in phases', function(done) {
const PHASES = [
var PHASES = [
'initial', 'session', 'auth', 'parse',
'routes', 'files', 'final',
];
@ -88,10 +88,10 @@ describe('app', function() {
return namedHandler(name);
}
let myHandler;
var myHandler;
app.middleware('routes:before',
myHandler = handlerThatAddsHandler('my-handler'));
const found = app._findLayerByHandler(myHandler);
var found = app._findLayerByHandler(myHandler);
expect(found).to.be.an('object');
expect(myHandler).to.equal(found.handle);
expect(found).have.property('phase', 'routes:before');
@ -106,35 +106,13 @@ describe('app', function() {
it('allows handlers to be wrapped as __NR_handler on express stack',
function(done) {
const myHandler = namedHandler('my-handler');
const wrappedHandler = function(req, res, next) {
var myHandler = namedHandler('my-handler');
var wrappedHandler = function(req, res, next) {
myHandler(req, res, next);
};
wrappedHandler['__NR_handler'] = myHandler;
app.middleware('routes:before', wrappedHandler);
const found = app._findLayerByHandler(myHandler);
expect(found).to.be.an('object');
expect(found).have.property('phase', 'routes:before');
executeMiddlewareHandlers(app, function(err) {
if (err) return done(err);
expect(steps).to.eql(['my-handler']);
done();
});
});
it('allows handlers to be wrapped as __appdynamicsProxyInfo__ on express stack',
function(done) {
const myHandler = namedHandler('my-handler');
const wrappedHandler = function(req, res, next) {
myHandler(req, res, next);
};
wrappedHandler['__appdynamicsProxyInfo__'] = {
orig: myHandler,
};
app.middleware('routes:before', wrappedHandler);
const found = app._findLayerByHandler(myHandler);
var found = app._findLayerByHandler(myHandler);
expect(found).to.be.an('object');
expect(found).have.property('phase', 'routes:before');
executeMiddlewareHandlers(app, function(err) {
@ -148,13 +126,13 @@ describe('app', function() {
it('allows handlers to be wrapped as a property on express stack',
function(done) {
const myHandler = namedHandler('my-handler');
const wrappedHandler = function(req, res, next) {
var myHandler = namedHandler('my-handler');
var wrappedHandler = function(req, res, next) {
myHandler(req, res, next);
};
wrappedHandler['__handler'] = myHandler;
app.middleware('routes:before', wrappedHandler);
const found = app._findLayerByHandler(myHandler);
var found = app._findLayerByHandler(myHandler);
expect(found).to.be.an('object');
expect(found).have.property('phase', 'routes:before');
executeMiddlewareHandlers(app, function(err) {
@ -167,7 +145,7 @@ describe('app', function() {
});
it('injects error from previous phases into the router', function(done) {
const expectedError = new Error('expected error');
var expectedError = new Error('expected error');
app.middleware('initial', function(req, res, next) {
steps.push('initial');
@ -193,7 +171,7 @@ describe('app', function() {
});
it('passes unhandled error to callback', function(done) {
const expectedError = new Error('expected error');
var expectedError = new Error('expected error');
app.middleware('initial', function(req, res, next) {
next(expectedError);
@ -207,8 +185,8 @@ describe('app', function() {
});
it('passes errors to error handlers in the same phase', function(done) {
const expectedError = new Error('this should be handled by middleware');
let handledError;
var expectedError = new Error('this should be handled by middleware');
var handledError;
app.middleware('initial', function(req, res, next) {
// continue in the next tick, this verifies that the next
@ -245,7 +223,7 @@ describe('app', function() {
expect(steps).to.eql(['/scope', '/scope/item']);
done();
},
}
);
});
@ -261,7 +239,7 @@ describe('app', function() {
expect(steps).to.eql(['/a', '/b']);
done();
},
}
);
});
@ -277,7 +255,7 @@ describe('app', function() {
expect(steps).to.eql(['/a', '/b', '/scope']);
done();
},
}
);
});
@ -298,7 +276,7 @@ describe('app', function() {
});
it('exposes express helpers on req and res objects', function(done) {
let req, res;
var req, res;
app.middleware('initial', function(rq, rs, next) {
req = rq;
@ -336,7 +314,7 @@ describe('app', function() {
});
it('sets req.baseUrl and req.originalUrl', function(done) {
let reqProps;
var reqProps;
app.middleware('initial', function(req, res, next) {
reqProps = {baseUrl: req.baseUrl, originalUrl: req.originalUrl};
@ -374,7 +352,7 @@ describe('app', function() {
// we need at least 9 elements to expose non-stability
// of the built-in sort function
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9];
var numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9];
numbers.forEach(function(n) {
app.middleware('routes', namedHandler(n));
});
@ -389,8 +367,8 @@ describe('app', function() {
});
it('correctly mounts express apps', function(done) {
let data, mountWasEmitted;
const subapp = express();
var data, mountWasEmitted;
var subapp = express();
subapp.use(function(req, res, next) {
data = {
mountpath: req.app.mountpath,
@ -417,10 +395,10 @@ describe('app', function() {
});
it('restores req & res on return from mounted express app', function(done) {
const expected = {};
const actual = {};
var expected = {};
var actual = {};
const subapp = express();
var subapp = express();
subapp.use(function verifyTestAssumptions(req, res, next) {
expect(req.__proto__).to.not.equal(expected.req);
expect(res.__proto__).to.not.equal(expected.res);
@ -468,8 +446,8 @@ describe('app', function() {
}
function getObjectAndPrototypeKeys(obj) {
const result = [];
for (const k in obj) {
var result = [];
for (var k in obj) {
result.push(k);
}
result.sort();
@ -479,11 +457,11 @@ describe('app', function() {
describe.onServer('.middlewareFromConfig', function() {
it('provides API for loading middleware from JSON config', function(done) {
const steps = [];
const expectedConfig = {key: 'value'};
var steps = [];
var expectedConfig = {key: 'value'};
const handlerFactory = function() {
const args = Array.prototype.slice.apply(arguments);
var handlerFactory = function() {
var args = Array.prototype.slice.apply(arguments);
return function(req, res, next) {
steps.push(args);
@ -550,7 +528,7 @@ describe('app', function() {
});
it('scopes middleware from config to a list of scopes', function(done) {
const steps = [];
var steps = [];
app.middlewareFromConfig(
function factory() {
return function(req, res, next) {
@ -562,7 +540,7 @@ describe('app', function() {
{
phase: 'initial',
paths: ['/scope', /^\/(a|b)/],
},
}
);
async.eachSeries(
@ -574,13 +552,13 @@ describe('app', function() {
expect(steps).to.eql(['/a', '/b', '/scope']);
done();
},
}
);
});
});
describe.onServer('.defineMiddlewarePhases(nameOrArray)', function() {
let app;
var app;
beforeEach(function() {
app = loopback();
});
@ -626,7 +604,7 @@ describe('app', function() {
});
function verifyMiddlewarePhases(names, done) {
const steps = [];
var steps = [];
names.forEach(function(it) {
app.middleware(it, function(req, res, next) {
steps.push(it);
@ -646,7 +624,7 @@ describe('app', function() {
});
describe('app.model(Model)', function() {
let app, db, MyTestModel;
var app, db, MyTestModel;
beforeEach(function() {
app = loopback();
app.set('remoting', {errorHandler: {debug: true, log: false}});
@ -655,7 +633,7 @@ describe('app', function() {
});
it('Expose a `Model` to remote clients', function() {
const Color = PersistedModel.extend('color', {name: String});
var Color = PersistedModel.extend('color', {name: String});
app.model(Color);
Color.attachTo(db);
@ -663,22 +641,22 @@ describe('app', function() {
});
it('uses singular name as app.remoteObjects() key', function() {
const Color = PersistedModel.extend('color', {name: String});
var Color = PersistedModel.extend('color', {name: String});
app.model(Color);
Color.attachTo(db);
expect(app.remoteObjects()).to.eql({color: Color});
});
it('uses singular name as shared class name', function() {
const Color = PersistedModel.extend('color', {name: String});
var Color = PersistedModel.extend('color', {name: String});
app.model(Color);
Color.attachTo(db);
const classes = app.remotes().classes().map(function(c) { return c.name; });
var classes = app.remotes().classes().map(function(c) { return c.name; });
expect(classes).to.contain('color');
});
it('registers existing models to app.models', function() {
const Color = db.createModel('color', {name: String});
var Color = db.createModel('color', {name: String});
app.model(Color);
expect(Color.app).to.be.equal(app);
expect(Color.shared).to.equal(true);
@ -687,9 +665,9 @@ describe('app', function() {
});
it('emits a `modelRemoted` event', function() {
const Color = PersistedModel.extend('color', {name: String});
var Color = PersistedModel.extend('color', {name: String});
Color.shared = true;
let remotedClass;
var remotedClass;
app.on('modelRemoted', function(sharedClass) {
remotedClass = sharedClass;
});
@ -699,9 +677,9 @@ describe('app', function() {
});
it('emits a `remoteMethodDisabled` event', function() {
const Color = PersistedModel.extend('color', {name: String});
var Color = PersistedModel.extend('color', {name: String});
Color.shared = true;
let remoteMethodDisabledClass, disabledRemoteMethod;
var remoteMethodDisabledClass, disabledRemoteMethod;
app.on('remoteMethodDisabled', function(sharedClass, methodName) {
remoteMethodDisabledClass = sharedClass;
disabledRemoteMethod = methodName;
@ -716,23 +694,23 @@ describe('app', function() {
it('emits a `remoteMethodAdded` event', function() {
app.dataSource('db', {connector: 'memory'});
const Book = app.registry.createModel(
var Book = app.registry.createModel(
'Book',
{name: 'string'},
{plural: 'books'},
{plural: 'books'}
);
app.model(Book, {dataSource: 'db'});
const Page = app.registry.createModel(
var Page = app.registry.createModel(
'Page',
{name: 'string'},
{plural: 'pages'},
{plural: 'pages'}
);
app.model(Page, {dataSource: 'db'});
Book.hasMany(Page);
let remoteMethodAddedClass;
var remoteMethodAddedClass;
app.on('remoteMethodAdded', function(sharedClass) {
remoteMethodAddedClass = sharedClass;
});
@ -741,6 +719,17 @@ describe('app', function() {
expect(remoteMethodAddedClass).to.eql(Book.sharedClass);
});
it.onServer('updates REST API when a new model is added', function(done) {
app.use(loopback.rest());
request(app).get('/colors').expect(404, function(err, res) {
if (err) return done(err);
var Color = PersistedModel.extend('color', {name: String});
app.model(Color);
Color.attachTo(db);
request(app).get('/colors').expect(200, done);
});
});
it('accepts null dataSource', function(done) {
app.model(MyTestModel, {dataSource: null});
expect(MyTestModel.dataSource).to.eql(null);
@ -759,14 +748,14 @@ describe('app', function() {
});
it('throws error if model typeof string is passed', function() {
const fn = function() { app.model('MyTestModel'); };
var fn = function() { app.model('MyTestModel'); };
expect(fn).to.throw(/app(\.model|\.registry)/);
});
});
describe('app.model(ModelCtor, config)', function() {
it('attaches the model to a datasource', function() {
const previousModel = loopback.registry.findModel('TestModel');
var previousModel = loopback.registry.findModel('TestModel');
app.dataSource('db', {connector: 'memory'});
if (previousModel) {
@ -774,7 +763,7 @@ describe('app', function() {
}
assert(!previousModel || !previousModel.dataSource);
const TestModel = app.registry.createModel('TestModel');
var TestModel = app.registry.createModel('TestModel');
app.model(TestModel, {dataSource: 'db'});
expect(app.models.TestModel.dataSource).to.equal(app.dataSources.db);
});
@ -843,10 +832,10 @@ describe('app', function() {
describe('app.models', function() {
it('is unique per app instance', function() {
app.dataSource('db', {connector: 'memory'});
const Color = app.registry.createModel('Color');
var Color = app.registry.createModel('Color');
app.model(Color, {dataSource: 'db'});
expect(app.models.Color).to.equal(Color);
const anotherApp = loopback();
var anotherApp = loopback();
expect(anotherApp.models.Color).to.equal(undefined);
});
});
@ -855,7 +844,7 @@ describe('app', function() {
it('is unique per app instance', function() {
app.dataSource('ds', {connector: 'memory'});
expect(app.datasources.ds).to.not.equal(undefined);
const anotherApp = loopback();
var anotherApp = loopback();
expect(anotherApp.datasources.ds).to.equal(undefined);
});
});
@ -886,11 +875,11 @@ describe('app', function() {
describe.onServer('listen()', function() {
it('starts http server', function(done) {
const app = loopback();
var app = loopback();
app.set('port', 0);
app.get('/', function(req, res) { res.status(200).send('OK'); });
const server = app.listen();
var server = app.listen();
expect(server).to.be.an.instanceOf(require('http').Server);
@ -900,7 +889,7 @@ describe('app', function() {
});
it('updates port on `listening` event', function(done) {
const app = loopback();
var app = loopback();
app.set('port', 0);
app.listen(function() {
@ -911,12 +900,12 @@ describe('app', function() {
});
it('updates `url` on `listening` event', function(done) {
const app = loopback();
var app = loopback();
app.set('port', 0);
app.set('host', undefined);
app.listen(function() {
const expectedUrl = 'http://localhost:' + app.get('port') + '/';
var expectedUrl = 'http://localhost:' + app.get('port') + '/';
expect(app.get('url'), 'url').to.equal(expectedUrl);
done();
@ -924,7 +913,7 @@ describe('app', function() {
});
it('forwards to http.Server.listen on more than one arg', function(done) {
const app = loopback();
var app = loopback();
app.set('port', 1);
app.listen(0, '127.0.0.1', function() {
expect(app.get('port'), 'port').to.not.equal(0).and.not.equal(1);
@ -935,7 +924,7 @@ describe('app', function() {
});
it('forwards to http.Server.listen when the single arg is not a function', function(done) {
const app = loopback();
var app = loopback();
app.set('port', 1);
app.listen(0).on('listening', function() {
expect(app.get('port'), 'port') .to.not.equal(0).and.not.equal(1);
@ -945,7 +934,7 @@ describe('app', function() {
});
it('uses app config when no parameter is supplied', function(done) {
const app = loopback();
var app = loopback();
// Http listens on all interfaces by default
// Custom host serves as an indicator whether
// the value was used by app.listen
@ -967,26 +956,26 @@ describe('app', function() {
});
it('auto-configures required models to provided dataSource', function() {
const AUTH_MODELS = ['User', 'ACL', 'AccessToken', 'Role', 'RoleMapping'];
const app = loopback({localRegistry: true, loadBuiltinModels: true});
var AUTH_MODELS = ['User', 'ACL', 'AccessToken', 'Role', 'RoleMapping'];
var app = loopback({localRegistry: true, loadBuiltinModels: true});
require('../lib/builtin-models')(app.registry);
const db = app.dataSource('db', {connector: 'memory'});
var db = app.dataSource('db', {connector: 'memory'});
app.enableAuth({dataSource: 'db'});
expect(Object.keys(app.models)).to.include.members(AUTH_MODELS);
AUTH_MODELS.forEach(function(m) {
const Model = app.models[m];
var Model = app.models[m];
expect(Model.dataSource, m + '.dataSource').to.equal(db);
expect(Model.shared, m + '.shared').to.equal(m === 'User');
});
});
it('detects already configured subclass of a required model', function() {
const app = loopback({localRegistry: true, loadBuiltinModels: true});
const db = app.dataSource('db', {connector: 'memory'});
const Customer = app.registry.createModel('Customer', {}, {base: 'User'});
var app = loopback({localRegistry: true, loadBuiltinModels: true});
var db = app.dataSource('db', {connector: 'memory'});
var Customer = app.registry.createModel('Customer', {}, {base: 'User'});
app.model(Customer, {dataSource: 'db'});
// Fix AccessToken's "belongsTo user" relation to use our new Customer model
@ -1001,7 +990,7 @@ describe('app', function() {
describe.onServer('app.get(\'/\', loopback.status())', function() {
it('should return the status of the application', function(done) {
const app = loopback();
var app = loopback();
app.get('/', loopback.status());
request(app)
.get('/')
@ -1013,7 +1002,7 @@ describe('app', function() {
expect(res.body).to.have.property('started');
expect(res.body.uptime, 'uptime').to.be.gte(0);
const elapsed = Date.now() - Number(new Date(res.body.started));
var elapsed = Date.now() - Number(new Date(res.body.started));
// elapsed should be a small positive number...
expect(elapsed, 'elapsed').to.be.within(0, 300);
@ -1026,7 +1015,7 @@ describe('app', function() {
describe('app.connectors', function() {
it('is unique per app instance', function() {
app.connectors.foo = 'bar';
const anotherApp = loopback();
var anotherApp = loopback();
expect(anotherApp.connectors.foo).to.equal(undefined);
});
@ -1069,8 +1058,8 @@ describe('app', function() {
});
it('is unique per app instance', function() {
const app1 = loopback();
const app2 = loopback();
var app1 = loopback();
var app2 = loopback();
expect(app1.settings).to.not.equal(app2.settings);
@ -1080,20 +1069,20 @@ describe('app', function() {
});
it('exposes loopback as a property', function() {
const app = loopback();
var app = loopback();
expect(app.loopback).to.equal(loopback);
});
function setupUserModels(app, options, done) {
app.dataSource('db', {connector: 'memory'});
const UserAccount = app.registry.createModel(
var UserAccount = app.registry.createModel(
'UserAccount',
{name: 'string'},
options,
options
);
const UserRole = app.registry.createModel(
var UserRole = app.registry.createModel(
'UserRole',
{name: 'string'},
{name: 'string'}
);
app.model(UserAccount, {dataSource: 'db'});
app.model(UserRole, {dataSource: 'db'});
@ -1108,7 +1097,7 @@ describe('app', function() {
}
describe('Model-level normalizeHttpPath option', function() {
let app;
var app;
beforeEach(function() {
app = loopback();
});
@ -1144,7 +1133,7 @@ describe('app', function() {
});
});
describe('app-level normalizeHttpPath option', function() {
let app;
var app;
beforeEach(function() {
app = loopback();
});
@ -1179,7 +1168,7 @@ describe('app', function() {
});
describe('Model-level and app-level normalizeHttpPath options', function() {
let app;
var app;
beforeEach(function() {
app = loopback();
});
@ -1203,8 +1192,8 @@ describe('app', function() {
});
function executeMiddlewareHandlers(app, urlPath, callback) {
let handlerError = undefined;
const server = http.createServer(function(req, res) {
var handlerError = undefined;
var server = http.createServer(function(req, res) {
app.handle(req, res, function(err) {
if (err) {
handlerError = err;

View File

@ -1,20 +1,20 @@
// Copyright IBM Corp. 2015,2019. All Rights Reserved.
// Copyright IBM Corp. 2015,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const expect = require('./helpers/expect');
const sinon = require('sinon');
const loopback = require('../');
var expect = require('./helpers/expect');
var sinon = require('sinon');
var loopback = require('../');
describe('PersistedModel.createChangeStream()', function() {
describe('configured to source changes locally', function() {
before(function() {
const test = this;
const app = loopback({localRegistry: true});
const ds = app.dataSource('ds', {connector: 'memory'});
const Score = app.registry.createModel('Score');
var test = this;
var app = loopback({localRegistry: true});
var ds = app.dataSource('ds', {connector: 'memory'});
var Score = app.registry.createModel('Score');
this.Score = app.model(Score, {
dataSource: 'ds',
changeDataSource: false, // use only local observers
@ -24,7 +24,7 @@ describe('PersistedModel.createChangeStream()', function() {
afterEach(verifyObserversRemoval);
it('should detect create', function(done) {
const Score = this.Score;
var Score = this.Score;
Score.createChangeStream(function(err, changes) {
changes.on('data', function(change) {
@ -38,7 +38,7 @@ describe('PersistedModel.createChangeStream()', function() {
});
it('should detect update', function(done) {
const Score = this.Score;
var Score = this.Score;
Score.create({team: 'foo'}, function(err, newScore) {
Score.createChangeStream(function(err, changes) {
changes.on('data', function(change) {
@ -55,7 +55,7 @@ describe('PersistedModel.createChangeStream()', function() {
});
it('should detect delete', function(done) {
const Score = this.Score;
var Score = this.Score;
Score.create({team: 'foo'}, function(err, newScore) {
Score.createChangeStream(function(err, changes) {
changes.on('data', function(change) {
@ -103,9 +103,9 @@ describe('PersistedModel.createChangeStream()', function() {
});
it('should not emit changes after destroy', function(done) {
const Score = this.Score;
var Score = this.Score;
const spy = sinon.spy();
var spy = sinon.spy();
Score.createChangeStream(function(err, changes) {
changes.on('data', function() {
@ -123,7 +123,7 @@ describe('PersistedModel.createChangeStream()', function() {
});
function verifyObserversRemoval() {
const Score = this.Score;
var Score = this.Score;
expect(Score._observers['after save']).to.be.empty();
expect(Score._observers['after delete']).to.be.empty();
}
@ -132,10 +132,10 @@ describe('PersistedModel.createChangeStream()', function() {
// TODO(ritch) implement multi-server support
describe.skip('configured to source changes using pubsub', function() {
before(function() {
const test = this;
const app = loopback({localRegistry: true});
const db = app.dataSource('ds', {connector: 'memory'});
const ps = app.dataSource('ps', {
var test = this;
var app = loopback({localRegistry: true});
var db = app.dataSource('ds', {connector: 'memory'});
var ps = app.dataSource('ps', {
host: 'localhost',
port: '12345',
connector: 'pubsub',
@ -148,7 +148,7 @@ describe('PersistedModel.createChangeStream()', function() {
});
it('should detect a change', function(done) {
const Score = this.Score;
var Score = this.Score;
Score.createChangeStream(function(err, changes) {
changes.on('data', function(change) {

View File

@ -1,19 +1,19 @@
// Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Copyright IBM Corp. 2014,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const assert = require('assert');
const async = require('async');
const expect = require('./helpers/expect');
const loopback = require('../');
var assert = require('assert');
var async = require('async');
var expect = require('./helpers/expect');
var loopback = require('../');
describe('Change', function() {
let Change, TestModel;
beforeEach(function() {
const memory = loopback.createDataSource({
var memory = loopback.createDataSource({
connector: loopback.Memory,
});
TestModel = loopback.PersistedModel.extend('ChangeTestModel',
@ -29,7 +29,7 @@ describe('Change', function() {
});
beforeEach(function(done) {
const test = this;
var test = this;
test.data = {
foo: 'bar',
};
@ -52,13 +52,13 @@ describe('Change', function() {
describe('change.id', function() {
it('should be a hash of the modelName and modelId', function() {
const change = new Change({
var change = new Change({
rev: 'abc',
modelName: 'foo',
modelId: 'bar',
});
const hash = Change.hash([change.modelName, change.modelId].join('-'));
var hash = Change.hash([change.modelName, change.modelId].join('-'));
assert.equal(change.id, hash);
});
@ -67,7 +67,7 @@ describe('Change', function() {
describe('Change.rectifyModelChanges(modelName, modelIds, callback)', function() {
describe('using an existing untracked model', function() {
beforeEach(function(done) {
const test = this;
var test = this;
Change.rectifyModelChanges(this.modelName, [this.modelId], function(err, trackedChanges) {
if (err) return done(err);
@ -76,7 +76,7 @@ describe('Change', function() {
});
it('should create an entry', function(done) {
const test = this;
var test = this;
Change.find(function(err, trackedChanges) {
assert.equal(trackedChanges[0].modelId, test.modelId.toString());
@ -97,7 +97,7 @@ describe('Change', function() {
describe('Change.rectifyModelChanges - promise variant', function() {
describe('using an existing untracked model', function() {
beforeEach(function(done) {
const test = this;
var test = this;
Change.rectifyModelChanges(this.modelName, [this.modelId])
.then(function(trackedChanges) {
done();
@ -106,7 +106,7 @@ describe('Change', function() {
});
it('should create an entry', function(done) {
const test = this;
var test = this;
Change.find()
.then(function(trackedChanges) {
assert.equal(trackedChanges[0].modelId, test.modelId.toString());
@ -131,7 +131,7 @@ describe('Change', function() {
describe('Change.findOrCreateChange(modelName, modelId, callback)', function() {
describe('when a change doesnt exist', function() {
beforeEach(function(done) {
const test = this;
var test = this;
Change.findOrCreateChange(this.modelName, this.modelId, function(err, result) {
if (err) return done(err);
@ -142,7 +142,7 @@ describe('Change', function() {
});
it('should create an entry', function(done) {
const test = this;
var test = this;
Change.findById(this.result.id, function(err, change) {
if (err) return done(err);
@ -155,7 +155,7 @@ describe('Change', function() {
describe('when a change doesnt exist - promise variant', function() {
beforeEach(function(done) {
const test = this;
var test = this;
Change.findOrCreateChange(this.modelName, this.modelId)
.then(function(result) {
test.result = result;
@ -166,7 +166,7 @@ describe('Change', function() {
});
it('should create an entry', function(done) {
const test = this;
var test = this;
Change.findById(this.result.id, function(err, change) {
if (err) return done(err);
@ -179,7 +179,7 @@ describe('Change', function() {
describe('when a change does exist', function() {
beforeEach(function(done) {
const test = this;
var test = this;
Change.create({
modelName: test.modelName,
modelId: test.modelId,
@ -191,7 +191,7 @@ describe('Change', function() {
});
beforeEach(function(done) {
const test = this;
var test = this;
Change.findOrCreateChange(this.modelName, this.modelId, function(err, result) {
if (err) return done(err);
@ -202,7 +202,7 @@ describe('Change', function() {
});
it('should find the entry', function(done) {
const test = this;
var test = this;
assert.equal(test.existingChange.id, test.result.id);
done();
@ -211,7 +211,7 @@ describe('Change', function() {
});
describe('change.rectify(callback)', function() {
let change;
var change;
beforeEach(function(done) {
Change.findOrCreate(
{
@ -222,12 +222,12 @@ describe('Change', function() {
change = ch;
done(err);
},
}
);
});
it('should create a new change with the correct revision', function(done) {
const test = this;
var test = this;
change.rectify(function(err, ch) {
assert.equal(ch.rev, test.revisionForModel);
@ -238,9 +238,9 @@ describe('Change', function() {
// This test is a low-level equivalent of the test in replication.test.js
// called "replicates multiple updates within the same CP"
it('should merge updates within the same checkpoint', function(done) {
const test = this;
const originalRev = this.revisionForModel;
let cp;
var test = this;
var originalRev = this.revisionForModel;
var cp;
async.series([
rectify,
@ -274,7 +274,7 @@ describe('Change', function() {
}
function update(next) {
const model = test.model;
var model = test.model;
model.name += 'updated';
model.save(function(err) {
@ -286,9 +286,9 @@ describe('Change', function() {
});
it('should not change checkpoint when rev is the same', function(done) {
const test = this;
const originalCheckpoint = change.checkpoint;
const originalRev = change.rev;
var test = this;
var originalCheckpoint = change.checkpoint;
var originalRev = change.rev;
TestModel.checkpoint(function(err, inst) {
if (err) return done(err);
@ -306,7 +306,7 @@ describe('Change', function() {
});
describe('change.rectify - promise variant', function() {
let change;
var change;
beforeEach(function(done) {
Change.findOrCreateChange(this.modelName, this.modelId)
.then(function(ch) {
@ -318,7 +318,7 @@ describe('Change', function() {
});
it('should create a new change with the correct revision', function(done) {
const test = this;
var test = this;
change.rectify()
.then(function(ch) {
assert.equal(ch.rev, test.revisionForModel);
@ -330,8 +330,8 @@ describe('Change', function() {
describe('change.currentRevision(callback)', function() {
it('should get the correct revision', function(done) {
const test = this;
const change = new Change({
var test = this;
var change = new Change({
modelName: this.modelName,
modelId: this.modelId,
});
@ -346,8 +346,8 @@ describe('Change', function() {
describe('change.currentRevision - promise variant', function() {
it('should get the correct revision', function(done) {
const test = this;
const change = new Change({
var test = this;
var change = new Change({
modelName: this.modelName,
modelId: this.modelId,
});
@ -365,8 +365,8 @@ describe('Change', function() {
describe('Change.hash(str)', function() {
// todo(ritch) test other hashing algorithms
it('should hash the given string', function() {
const str = 'foo';
const hash = Change.hash(str);
var str = 'foo';
var hash = Change.hash(str);
assert(hash !== str);
assert(typeof hash === 'string');
});
@ -374,54 +374,54 @@ describe('Change', function() {
describe('Change.revisionForInst(inst)', function() {
it('should return the same revision for the same data', function() {
const a = {
var a = {
b: {
b: ['c', 'd'],
c: ['d', 'e'],
},
};
const b = {
var b = {
b: {
c: ['d', 'e'],
b: ['c', 'd'],
},
};
const aRev = Change.revisionForInst(a);
const bRev = Change.revisionForInst(b);
var aRev = Change.revisionForInst(a);
var bRev = Change.revisionForInst(b);
assert.equal(aRev, bRev);
});
});
describe('change.type()', function() {
it('CREATE', function() {
const change = new Change({
var change = new Change({
rev: this.revisionForModel,
});
assert.equal(Change.CREATE, change.type());
});
it('UPDATE', function() {
const change = new Change({
var change = new Change({
rev: this.revisionForModel,
prev: this.revisionForModel,
});
assert.equal(Change.UPDATE, change.type());
});
it('DELETE', function() {
const change = new Change({
var change = new Change({
prev: this.revisionForModel,
});
assert.equal(Change.DELETE, change.type());
});
it('UNKNOWN', function() {
const change = new Change();
var change = new Change();
assert.equal(Change.UNKNOWN, change.type());
});
});
describe('change.getModelCtor()', function() {
it('should get the correct model class', function() {
const change = new Change({
var change = new Change({
modelName: this.modelName,
});
@ -431,11 +431,11 @@ describe('Change', function() {
describe('change.equals(otherChange)', function() {
it('should return true when the change is equal', function() {
const change = new Change({
var change = new Change({
rev: this.revisionForModel,
});
const otherChange = new Change({
var otherChange = new Change({
rev: this.revisionForModel,
});
@ -443,13 +443,13 @@ describe('Change', function() {
});
it('should return true when both changes are deletes', function() {
const REV = 'foo';
const change = new Change({
var REV = 'foo';
var change = new Change({
rev: null,
prev: REV,
});
const otherChange = new Change({
var otherChange = new Change({
rev: undefined,
prev: REV,
});
@ -463,11 +463,11 @@ describe('Change', function() {
describe('change.isBasedOn(otherChange)', function() {
it('should return true when the change is based on the other', function() {
const change = new Change({
var change = new Change({
prev: this.revisionForModel,
});
const otherChange = new Change({
var otherChange = new Change({
rev: this.revisionForModel,
});
@ -485,7 +485,7 @@ describe('Change', function() {
});
it('should return delta and conflict lists', function(done) {
const remoteChanges = [
var remoteChanges = [
// an update => should result in a delta
{rev: 'foo2', prev: 'foo', modelName: this.modelName, modelId: 9, checkpoint: 1},
// no change => should not result in a delta / conflict
@ -505,7 +505,7 @@ describe('Change', function() {
});
it('should return delta and conflict lists - promise variant', function(done) {
const remoteChanges = [
var remoteChanges = [
// an update => should result in a delta
{rev: 'foo2', prev: 'foo', modelName: this.modelName, modelId: 9, checkpoint: 1},
// no change => should not result in a delta / conflict
@ -525,7 +525,7 @@ describe('Change', function() {
});
it('should set "prev" to local revision in non-conflicting delta', function(done) {
const updateRecord = {
var updateRecord = {
rev: 'foo-new',
prev: 'foo',
modelName: this.modelName,
@ -537,7 +537,7 @@ describe('Change', function() {
expect(diff.conflicts, 'conflicts').to.have.length(0);
expect(diff.deltas, 'deltas').to.have.length(1);
const actual = diff.deltas[0].toObject();
var actual = diff.deltas[0].toObject();
delete actual.id;
expect(actual).to.eql({
checkpoint: 2,
@ -552,7 +552,7 @@ describe('Change', function() {
});
it('should set "prev" to local revision in remote-only delta', function(done) {
const updateRecord = {
var updateRecord = {
rev: 'foo-new',
prev: 'foo-prev',
modelName: this.modelName,
@ -566,7 +566,7 @@ describe('Change', function() {
expect(diff.conflicts, 'conflicts').to.have.length(0);
expect(diff.deltas, 'deltas').to.have.length(1);
const actual = diff.deltas[0].toObject();
var actual = diff.deltas[0].toObject();
delete actual.id;
expect(actual).to.eql({
checkpoint: 2,
@ -581,7 +581,7 @@ describe('Change', function() {
});
it('should set "prev" to null for a new instance', function(done) {
const updateRecord = {
var updateRecord = {
rev: 'new-rev',
prev: 'new-prev',
modelName: this.modelName,
@ -594,7 +594,7 @@ describe('Change', function() {
expect(diff.conflicts).to.have.length(0);
expect(diff.deltas).to.have.length(1);
const actual = diff.deltas[0].toObject();
var actual = diff.deltas[0].toObject();
delete actual.id;
expect(actual).to.eql({
checkpoint: 2,
@ -614,7 +614,7 @@ describe('Change with with custom properties', function() {
let Change, TestModel;
beforeEach(function() {
const memory = loopback.createDataSource({
let memory = loopback.createDataSource({
connector: loopback.Memory,
});
@ -630,7 +630,7 @@ describe('Change with with custom properties', function() {
this.modelName = TestModel.modelName;
TestModel.prototype.fillCustomChangeProperties = function(change, cb) {
const inst = this;
var inst = this;
if (inst && inst.tenantId) {
change.tenantId = inst.tenantId;

View File

@ -1,19 +1,19 @@
// Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Copyright IBM Corp. 2014,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const async = require('async');
const loopback = require('../');
const expect = require('./helpers/expect');
var async = require('async');
var loopback = require('../');
var expect = require('./helpers/expect');
const Checkpoint = loopback.Checkpoint.extend('TestCheckpoint');
var Checkpoint = loopback.Checkpoint.extend('TestCheckpoint');
describe('Checkpoint', function() {
describe('bumpLastSeq() and current()', function() {
beforeEach(function() {
const memory = loopback.createDataSource({
var memory = loopback.createDataSource({
connector: loopback.Memory,
});
Checkpoint.attachTo(memory);

View File

@ -1,16 +1,16 @@
// Copyright IBM Corp. 2016,2019. All Rights Reserved.
// Copyright IBM Corp. 2016,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const expect = require('chai').expect;
const loopback = require('..');
const supertest = require('supertest');
var expect = require('chai').expect;
var loopback = require('..');
var supertest = require('supertest');
describe('OptionsFromRemotingContext', function() {
let app, request, accessToken, userId, Product, actualOptions;
var app, request, accessToken, userId, Product, actualOptions;
beforeEach(setupAppAndRequest);
beforeEach(resetActualOptions);
@ -133,7 +133,7 @@ describe('OptionsFromRemotingContext', function() {
// despite the fact that under the hood a method on "modelTo" is called.
context('hasManyThrough', function() {
let Category, ThroughModel;
var Category, ThroughModel;
beforeEach(givenCategoryHasManyProductsThroughAnotherModel);
beforeEach(givenCategoryAndProduct);
@ -215,7 +215,7 @@ describe('OptionsFromRemotingContext', function() {
Category = app.registry.createModel(
'Category',
{name: String},
{forceId: false, replaceOnPUT: true},
{forceId: false, replaceOnPUT: true}
);
app.model(Category, {dataSource: 'db'});
@ -242,7 +242,7 @@ describe('OptionsFromRemotingContext', function() {
});
context('hasOne', function() {
let Category;
var Category;
beforeEach(givenCategoryHasOneProduct);
beforeEach(givenCategoryId1);
@ -288,7 +288,7 @@ describe('OptionsFromRemotingContext', function() {
Category = app.registry.createModel(
'Category',
{name: String},
{forceId: false, replaceOnPUT: true},
{forceId: false, replaceOnPUT: true}
);
app.model(Category, {dataSource: 'db'});
@ -313,7 +313,7 @@ describe('OptionsFromRemotingContext', function() {
});
context('belongsTo', function() {
let Category;
var Category;
beforeEach(givenCategoryBelongsToProduct);
@ -333,7 +333,7 @@ describe('OptionsFromRemotingContext', function() {
Category = app.registry.createModel(
'Category',
{name: String},
{forceId: false, replaceOnPUT: true},
{forceId: false, replaceOnPUT: true}
);
app.model(Category, {dataSource: 'db'});
@ -364,7 +364,7 @@ describe('OptionsFromRemotingContext', function() {
Product = app.registry.createModel(
'Product',
{name: String},
{forceId: false, replaceOnPUT: true},
{forceId: false, replaceOnPUT: true}
);
Product.createOptionsFromRemotingContext = function(ctx) {
@ -382,7 +382,7 @@ describe('OptionsFromRemotingContext', function() {
}
function observeOptionsBeforeSave() {
const Model = arguments[0] || Product;
var Model = arguments[0] || Product;
Model.observe('before save', function(ctx, next) {
actualOptions = ctx.options;
next();
@ -390,7 +390,7 @@ describe('OptionsFromRemotingContext', function() {
}
function observeOptionsBeforeDelete() {
const Model = arguments[0] || Product;
var Model = arguments[0] || Product;
Model.observe('before delete', function(ctx, next) {
actualOptions = ctx.options;
next();
@ -398,7 +398,7 @@ describe('OptionsFromRemotingContext', function() {
}
function observeOptionsOnAccess() {
const Model = arguments[0] || Product;
var Model = arguments[0] || Product;
Model.observe('access', function(ctx, next) {
actualOptions = ctx.options;
next();

View File

@ -1,14 +1,14 @@
// Copyright IBM Corp. 2013,2019. All Rights Reserved.
// Copyright IBM Corp. 2013,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const assert = require('assert');
const loopback = require('../');
var assert = require('assert');
var loopback = require('../');
describe('DataSource', function() {
let memory;
var memory;
beforeEach(function() {
memory = loopback.createDataSource({
@ -20,7 +20,7 @@ describe('DataSource', function() {
describe('dataSource.createModel(name, properties, settings)', function() {
it('Define a model and attach it to a `DataSource`', function() {
const Color = memory.createModel('color', {name: String});
var Color = memory.createModel('color', {name: String});
assert.isFunc(Color, 'find');
assert.isFunc(Color, 'findById');
assert.isFunc(Color, 'findOne');
@ -45,31 +45,31 @@ describe('DataSource', function() {
});
it('should honor settings.base', function() {
const Base = memory.createModel('base');
const Color = memory.createModel('color', {name: String}, {base: Base});
var Base = memory.createModel('base');
var Color = memory.createModel('color', {name: String}, {base: Base});
assert(Color.prototype instanceof Base);
assert.equal(Color.base, Base);
});
it('should use loopback.PersistedModel as the base for DBs', function() {
const Color = memory.createModel('color', {name: String});
var Color = memory.createModel('color', {name: String});
assert(Color.prototype instanceof loopback.PersistedModel);
assert.equal(Color.base, loopback.PersistedModel);
});
it('should use loopback.Model as the base for non DBs', function() {
// Mock up a non-DB connector
const Connector = function() {
var Connector = function() {
};
Connector.prototype.getTypes = function() {
return ['rest'];
};
const ds = loopback.createDataSource({
var ds = loopback.createDataSource({
connector: new Connector(),
});
const Color = ds.createModel('color', {name: String});
var Color = ds.createModel('color', {name: String});
assert(Color.prototype instanceof Color.registry.getModel('Model'));
assert.equal(Color.base.modelName, 'PersistedModel');
});
@ -77,7 +77,7 @@ describe('DataSource', function() {
describe.skip('PersistedModel Methods', function() {
it('List the enabled and disabled methods', function() {
const TestModel = loopback.PersistedModel.extend('TestPersistedModel');
var TestModel = loopback.PersistedModel.extend('TestPersistedModel');
TestModel.attachTo(loopback.memory());
// assert the defaults
@ -109,9 +109,9 @@ describe('DataSource', function() {
existsAndShared('reload', false);
function existsAndShared(Model, name, isRemoteEnabled, isProto) {
const scope = isProto ? Model.prototype : Model;
const fn = scope[name];
const actuallyEnabled = Model.getRemoteMethod(name);
var scope = isProto ? Model.prototype : Model;
var fn = scope[name];
var actuallyEnabled = Model.getRemoteMethod(name);
assert(fn, name + ' should be defined!');
assert(actuallyEnabled === isRemoteEnabled,
name + ' ' + (isRemoteEnabled ? 'should' : 'should not') +
@ -121,7 +121,7 @@ describe('DataSource', function() {
});
});
function assertValidDataSource(dataSource) {
var assertValidDataSource = function(dataSource) {
// has methods
assert.isFunc(dataSource, 'createModel');
assert.isFunc(dataSource, 'discoverModelDefinitions');
@ -130,7 +130,7 @@ function assertValidDataSource(dataSource) {
assert.isFunc(dataSource, 'disableRemote');
assert.isFunc(dataSource, 'defineOperation');
assert.isFunc(dataSource, 'operations');
}
};
assert.isFunc = function(obj, name) {
assert(obj, 'cannot assert function ' + name + ' on object that doesnt exist');

View File

@ -1,19 +1,19 @@
// Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Copyright IBM Corp. 2014,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const path = require('path');
const loopback = require('../../');
const models = require('../fixtures/e2e/models');
const TestModel = models.TestModel;
const assert = require('assert');
var path = require('path');
var loopback = require('../../');
var models = require('../fixtures/e2e/models');
var TestModel = models.TestModel;
var assert = require('assert');
describe('RemoteConnector', function() {
before(function() {
// setup the remote connector
const ds = loopback.createDataSource({
var ds = loopback.createDataSource({
url: 'http://127.0.0.1:3000/api',
connector: loopback.Remote,
});
@ -33,7 +33,7 @@ describe('RemoteConnector', function() {
});
it('should be able to call save', function(done) {
const m = new TestModel({
var m = new TestModel({
foo: 'bar',
});
m.save(function(err, data) {

View File

@ -1,32 +1,32 @@
// Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Copyright IBM Corp. 2014,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const path = require('path');
const loopback = require('../../');
const models = require('../fixtures/e2e/models');
const TestModel = models.TestModel;
const LocalTestModel = TestModel.extend('LocalTestModel', {}, {
var path = require('path');
var loopback = require('../../');
var models = require('../fixtures/e2e/models');
var TestModel = models.TestModel;
var LocalTestModel = TestModel.extend('LocalTestModel', {}, {
trackChanges: true,
});
const assert = require('assert');
var assert = require('assert');
describe('Replication', function() {
before(function() {
// setup the remote connector
const ds = loopback.createDataSource({
var ds = loopback.createDataSource({
url: 'http://127.0.0.1:3000/api',
connector: loopback.Remote,
});
TestModel.attachTo(ds);
const memory = loopback.memory();
var memory = loopback.memory();
LocalTestModel.attachTo(memory);
});
it('should replicate local data to the remote', function(done) {
const RANDOM = Math.random();
var RANDOM = Math.random();
LocalTestModel.create({
n: RANDOM,

View File

@ -1,38 +1,38 @@
// Copyright IBM Corp. 2013,2019. All Rights Reserved.
// Copyright IBM Corp. 2013,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const loopback = require('../');
let MyEmail;
const assert = require('assert');
const MailConnector = require('../lib/connectors/mail');
var loopback = require('../');
var MyEmail;
var assert = require('assert');
var MailConnector = require('../lib/connectors/mail');
describe('Email connector', function() {
it('should set up SMTP', function() {
const connector = new MailConnector({transports: [
var connector = new MailConnector({transports: [
{type: 'smtp', service: 'gmail'},
]});
assert(connector.transportForName('smtp'));
});
it('should set up DIRECT', function() {
const connector = new MailConnector({transports: [
var connector = new MailConnector({transports: [
{type: 'direct', name: 'localhost'},
]});
assert(connector.transportForName('direct'));
});
it('should set up STUB', function() {
const connector = new MailConnector({transports: [
var connector = new MailConnector({transports: [
{type: 'stub', service: 'gmail'},
]});
assert(connector.transportForName('stub'));
});
it('should set up a single transport for SMTP', function() {
const connector = new MailConnector({transport:
var connector = new MailConnector({transport:
{type: 'smtp', service: 'gmail'},
});
@ -40,7 +40,7 @@ describe('Email connector', function() {
});
it('should set up a aliased transport for SMTP', function() {
const connector = new MailConnector({transport:
var connector = new MailConnector({transport:
{type: 'smtp', service: 'ses-us-east-1', alias: 'ses-smtp'},
});
@ -51,7 +51,7 @@ describe('Email connector', function() {
describe('Email and SMTP', function() {
beforeEach(function() {
MyEmail = loopback.Email.extend('my-email');
const ds = loopback.createDataSource('email', {
var ds = loopback.createDataSource('email', {
connector: loopback.Mail,
transports: [{type: 'STUB'}],
});
@ -65,7 +65,7 @@ describe('Email and SMTP', function() {
describe('MyEmail', function() {
it('MyEmail.send(options, callback)', function(done) {
const options = {
var options = {
to: 'to@to.com',
from: 'from@from.com',
subject: 'subject',
@ -84,7 +84,7 @@ describe('Email and SMTP', function() {
});
it('myEmail.send(callback)', function(done) {
const message = new MyEmail({
var message = new MyEmail({
to: 'to@to.com',
from: 'from@from.com',
subject: 'subject',

View File

@ -1,14 +1,14 @@
// Copyright IBM Corp. 2015,2019. All Rights Reserved.
// Copyright IBM Corp. 2015,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const loopback = require('../');
let app;
const assert = require('assert');
const request = require('supertest');
const expect = require('./helpers/expect');
var loopback = require('../');
var app;
var assert = require('assert');
var request = require('supertest');
var expect = require('./helpers/expect');
describe('loopback.errorHandler(options)', function() {
it('should throw a descriptive error', function() {

View File

@ -1,20 +1,20 @@
// Copyright IBM Corp. 2015,2019. All Rights Reserved.
// Copyright IBM Corp. 2015,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const loopback = require('../../../..');
const boot = require('loopback-boot');
const app = module.exports = loopback({
var loopback = require('../../../..');
var boot = require('loopback-boot');
var app = module.exports = loopback({
localRegistry: true,
loadBuiltinModels: true,
});
const errorHandler = require('strong-error-handler');
var errorHandler = require('strong-error-handler');
boot(app, __dirname);
const apiPath = '/api';
var apiPath = '/api';
app.use(loopback.token({model: app.models.accessToken}));
app.use(apiPath, loopback.rest());

View File

@ -1,11 +1,11 @@
// Copyright IBM Corp. 2015,2019. All Rights Reserved.
// Copyright IBM Corp. 2015,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const loopback = require('../../../../index');
const PersistedModel = loopback.PersistedModel;
var loopback = require('../../../../index');
var PersistedModel = loopback.PersistedModel;
exports.TestModel = PersistedModel.extend('TestModel', {}, {
trackChanges: true,

View File

@ -1,15 +1,15 @@
// Copyright IBM Corp. 2015,2019. All Rights Reserved.
// Copyright IBM Corp. 2015,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const loopback = require('../../../../index');
const app = module.exports = loopback({localRegistry: true});
const models = require('./models');
const TestModel = models.TestModel;
var loopback = require('../../../../index');
var app = module.exports = loopback({localRegistry: true});
var models = require('./models');
var TestModel = models.TestModel;
const apiPath = '/api';
var apiPath = '/api';
app.use(apiPath, loopback.rest());
TestModel.attachTo(loopback.memory());

View File

@ -1,12 +1,12 @@
// Copyright IBM Corp. 2015,2019. All Rights Reserved.
// Copyright IBM Corp. 2015,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const boot = require('loopback-boot');
const loopback = require('../../../../../index');
var boot = require('loopback-boot');
var loopback = require('../../../../../index');
const app = module.exports = loopback();
var app = module.exports = loopback();
boot(app, __dirname);
app.use(loopback.rest());

View File

@ -1,12 +1,12 @@
// Copyright IBM Corp. 2015,2019. All Rights Reserved.
// Copyright IBM Corp. 2015,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const boot = require('loopback-boot');
const loopback = require('../../../../../index');
var boot = require('loopback-boot');
var loopback = require('../../../../../index');
const app = module.exports = loopback();
var app = module.exports = loopback();
boot(app, __dirname);
app.use(loopback.rest());

View File

@ -1,12 +1,12 @@
// Copyright IBM Corp. 2015,2019. All Rights Reserved.
// Copyright IBM Corp. 2015,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const boot = require('loopback-boot');
const loopback = require('../../../../../index');
var boot = require('loopback-boot');
var loopback = require('../../../../../index');
const app = module.exports = loopback();
var app = module.exports = loopback();
boot(app, __dirname);
app.use(loopback.rest());

View File

@ -1,12 +1,12 @@
// Copyright IBM Corp. 2015,2019. All Rights Reserved.
// Copyright IBM Corp. 2015,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const boot = require('loopback-boot');
const loopback = require('../../../../../index');
var boot = require('loopback-boot');
var loopback = require('../../../../../index');
const app = module.exports = loopback();
var app = module.exports = loopback();
boot(app, __dirname);
app.use(loopback.rest());

View File

@ -1,12 +1,12 @@
// Copyright IBM Corp. 2015,2019. All Rights Reserved.
// Copyright IBM Corp. 2015,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const boot = require('loopback-boot');
const loopback = require('../../../../../index');
var boot = require('loopback-boot');
var loopback = require('../../../../../index');
const app = module.exports = loopback();
var app = module.exports = loopback();
boot(app, __dirname);
app.use(loopback.rest());

View File

@ -1,12 +1,12 @@
// Copyright IBM Corp. 2015,2019. All Rights Reserved.
// Copyright IBM Corp. 2015,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const boot = require('loopback-boot');
const loopback = require('../../../../../index');
var boot = require('loopback-boot');
var loopback = require('../../../../../index');
const app = module.exports = loopback();
var app = module.exports = loopback();
boot(app, __dirname);
app.use(loopback.rest());

View File

@ -1,12 +1,12 @@
// Copyright IBM Corp. 2015,2019. All Rights Reserved.
// Copyright IBM Corp. 2015,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const boot = require('loopback-boot');
const loopback = require('../../../../../index');
var boot = require('loopback-boot');
var loopback = require('../../../../../index');
const app = module.exports = loopback();
var app = module.exports = loopback();
boot(app, __dirname);
app.use(loopback.rest());

View File

@ -1,12 +1,12 @@
// Copyright IBM Corp. 2015,2019. All Rights Reserved.
// Copyright IBM Corp. 2015,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const boot = require('loopback-boot');
const loopback = require('../../../../../index');
var boot = require('loopback-boot');
var loopback = require('../../../../../index');
const app = module.exports = loopback();
var app = module.exports = loopback();
boot(app, __dirname);
app.use(loopback.rest());

View File

@ -1,12 +1,12 @@
// Copyright IBM Corp. 2015,2019. All Rights Reserved.
// Copyright IBM Corp. 2015,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const boot = require('loopback-boot');
const loopback = require('../../../../../index');
var boot = require('loopback-boot');
var loopback = require('../../../../../index');
const app = module.exports = loopback();
var app = module.exports = loopback();
boot(app, __dirname);
app.use(loopback.rest());

View File

@ -1,16 +1,16 @@
// Copyright IBM Corp. 2015,2019. All Rights Reserved.
// Copyright IBM Corp. 2015,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const loopback = require('../../../../index');
const boot = require('loopback-boot');
const app = module.exports = loopback({localRegistry: true});
const errorHandler = require('strong-error-handler');
var loopback = require('../../../../index');
var boot = require('loopback-boot');
var app = module.exports = loopback({localRegistry: true});
var errorHandler = require('strong-error-handler');
boot(app, __dirname);
const apiPath = '/api';
var apiPath = '/api';
app.use(apiPath, loopback.rest());
app.use(loopback.urlNotFound());
app.use(errorHandler());

View File

@ -1,21 +1,21 @@
// Copyright IBM Corp. 2015,2019. All Rights Reserved.
// Copyright IBM Corp. 2015,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const loopback = require('../../../../index');
const boot = require('loopback-boot');
const app = module.exports = loopback({
var loopback = require('../../../../index');
var boot = require('loopback-boot');
var app = module.exports = loopback({
localRegistry: true,
loadBuiltinModels: true,
});
const errorHandler = require('strong-error-handler');
var errorHandler = require('strong-error-handler');
app.enableAuth();
boot(app, __dirname);
app.use(loopback.token({model: app.models.AccessToken}));
const apiPath = '/api';
var apiPath = '/api';
app.use(apiPath, loopback.rest());
app.use(loopback.urlNotFound());
app.use(errorHandler());

View File

@ -1,19 +1,19 @@
// Copyright IBM Corp. 2013,2019. All Rights Reserved.
// Copyright IBM Corp. 2013,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const assert = require('assert');
const loopback = require('../');
const GeoPoint = loopback.GeoPoint;
var assert = require('assert');
var loopback = require('../');
var GeoPoint = loopback.GeoPoint;
describe('GeoPoint', function() {
describe('geoPoint.distanceTo(geoPoint, options)', function() {
it('Get the distance to another `GeoPoint`', function() {
const here = new GeoPoint({lat: 10, lng: 10});
const there = new GeoPoint({lat: 5, lng: 5});
const distance = here.distanceTo(there, {type: 'meters'});
var here = new GeoPoint({lat: 10, lng: 10});
var there = new GeoPoint({lat: 5, lng: 5});
var distance = here.distanceTo(there, {type: 'meters'});
assert.equal(Math.floor(distance), 782777);
});
@ -21,9 +21,9 @@ describe('GeoPoint', function() {
describe('GeoPoint.distanceBetween(a, b, options)', function() {
it('Get the distance between two points', function() {
const here = new GeoPoint({lat: 10, lng: 10});
const there = new GeoPoint({lat: 5, lng: 5});
const distance = GeoPoint.distanceBetween(here, there, {type: 'feet'});
var here = new GeoPoint({lat: 10, lng: 10});
var there = new GeoPoint({lat: 5, lng: 5});
var distance = GeoPoint.distanceBetween(here, there, {type: 'feet'});
assert.equal(Math.floor(distance), 2568169);
});
@ -31,32 +31,32 @@ describe('GeoPoint', function() {
describe('GeoPoint()', function() {
it('Create from string', function() {
const point = new GeoPoint('1.234,5.678');
var point = new GeoPoint('1.234,5.678');
assert.equal(point.lat, 1.234);
assert.equal(point.lng, 5.678);
const point2 = new GeoPoint('1.222, 5.333');
var point2 = new GeoPoint('1.222, 5.333');
assert.equal(point2.lat, 1.222);
assert.equal(point2.lng, 5.333);
const point3 = new GeoPoint('1.333, 5.111');
var point3 = new GeoPoint('1.333, 5.111');
assert.equal(point3.lat, 1.333);
assert.equal(point3.lng, 5.111);
});
it('Serialize as string', function() {
const str = '1.234,5.678';
const point = new GeoPoint(str);
var str = '1.234,5.678';
var point = new GeoPoint(str);
assert.equal(point.toString(), str);
});
it('Create from array', function() {
const point = new GeoPoint([5.555, 6.777]);
var point = new GeoPoint([5.555, 6.777]);
assert.equal(point.lat, 5.555);
assert.equal(point.lng, 6.777);
});
it('Create as Model property', function() {
const Model = loopback.createModel('geo-model', {
var Model = loopback.createModel('geo-model', {
geo: {type: 'GeoPoint'},
});
const m = new Model({
var m = new Model({
geo: '1.222,3.444',
});

View File

@ -1,11 +1,11 @@
// Copyright IBM Corp. 2016,2019. All Rights Reserved.
// Copyright IBM Corp. 2016,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const chai = require('chai');
var chai = require('chai');
chai.use(require('dirty-chai'));
chai.use(require('sinon-chai'));

View File

@ -1,24 +1,24 @@
// Copyright IBM Corp. 2015,2019. All Rights Reserved.
// Copyright IBM Corp. 2015,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const _describe = {};
const _it = {};
const _beforeEach = {};
const helpers = {
var _describe = {};
var _it = {};
var _beforeEach = {};
var helpers = {
describe: _describe,
it: _it,
beforeEach: _beforeEach,
};
module.exports = helpers;
const assert = require('assert');
const request = require('supertest');
const chai = require('chai');
const expect = chai.expect;
const sinon = require('sinon');
var assert = require('assert');
var request = require('supertest');
var chai = require('chai');
var expect = chai.expect;
var sinon = require('sinon');
chai.use(require('sinon-chai'));
_beforeEach.withApp = function(app) {
@ -29,7 +29,7 @@ _beforeEach.withApp = function(app) {
beforeEach(function(done) {
this.app = app;
const _request = this.request = request(app);
var _request = this.request = request(app);
this.post = _request.post;
this.get = _request.get;
this.put = _request.put;
@ -45,14 +45,14 @@ _beforeEach.withApp = function(app) {
};
_beforeEach.withArgs = function() {
const args = Array.prototype.slice.call(arguments, 0);
var args = Array.prototype.slice.call(arguments, 0);
beforeEach(function() {
this.args = args;
});
};
_beforeEach.givenModel = function(modelName, attrs, optionalHandler) {
let modelKey = modelName;
var modelKey = modelName;
if (typeof attrs === 'function') {
optionalHandler = attrs;
@ -66,9 +66,9 @@ _beforeEach.givenModel = function(modelName, attrs, optionalHandler) {
attrs = attrs || {};
beforeEach(function(done) {
const test = this;
const app = this.app;
const model = app.models[modelName];
var test = this;
var app = this.app;
var model = app.models[modelName];
app.set('remoting', {errorHandler: {debug: true, log: false}});
assert(model, 'cannot get model of name ' + modelName + ' from app.models');
@ -76,7 +76,7 @@ _beforeEach.givenModel = function(modelName, attrs, optionalHandler) {
' without attached dataSource');
assert(
typeof model.create === 'function',
modelName + ' does not have a create method',
modelName + ' does not have a create method'
);
model.create(attrs, function(err, result) {
@ -108,7 +108,7 @@ _beforeEach.givenUser = function(attrs, optionalHandler) {
_beforeEach.givenLoggedInUser = function(credentials, optionalHandler) {
_beforeEach.givenUser(credentials, function(done) {
const test = this;
var test = this;
this.user.constructor.login(credentials, function(err, token) {
if (err) {
done(err);
@ -121,7 +121,7 @@ _beforeEach.givenLoggedInUser = function(credentials, optionalHandler) {
});
afterEach(function(done) {
const test = this;
var test = this;
this.loggedInAccessToken.destroy(function(err) {
if (err) return done(err);
@ -146,7 +146,7 @@ _describe.whenCalledRemotely = function(verb, url, data, cb) {
data = null;
}
let urlStr = url;
var urlStr = url;
if (typeof url === 'function') {
urlStr = '/<dynamic>';
}
@ -159,11 +159,11 @@ _describe.whenCalledRemotely = function(verb, url, data, cb) {
this.remotely = true;
this.verb = verb.toUpperCase();
this.url = this.url || url;
let methodForVerb = verb.toLowerCase();
var methodForVerb = verb.toLowerCase();
if (methodForVerb === 'delete') methodForVerb = 'del';
if (this.request === undefined) {
const msg = 'App is not specified. ' +
var msg = 'App is not specified. ' +
'Please use lt.beforeEach.withApp to specify the app.';
throw new Error(msg);
}
@ -175,13 +175,13 @@ _describe.whenCalledRemotely = function(verb, url, data, cb) {
this.http.set('authorization', this.loggedInAccessToken.id);
}
if (data) {
let payload = data;
var payload = data;
if (typeof data === 'function')
payload = data.call(this);
this.http.send(payload);
}
this.req = this.http.req;
const test = this;
var test = this;
this.http.end(function(err) {
test.req = test.http.req;
test.res = test.http.response;
@ -236,7 +236,7 @@ _it.shouldBeAllowed = function() {
_it.shouldBeDenied = function() {
it('should not be allowed', function() {
assert(this.res);
const expectedStatus = this.aclErrorStatus ||
var expectedStatus = this.aclErrorStatus ||
this.app && this.app.get('aclErrorStatus') ||
401;
expect(this.res.statusCode).to.equal(expectedStatus);

View File

@ -1,11 +1,11 @@
// Copyright IBM Corp. 2017,2019. All Rights Reserved.
// Copyright IBM Corp. 2017,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const env = process.env;
var env = process.env;
// delete any user-provided language settings
delete env.LC_ALL;

View File

@ -1,24 +1,24 @@
// Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Copyright IBM Corp. 2014,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const assert = require('assert');
const loopback = require('../');
const request = require('supertest');
var assert = require('assert');
var loopback = require('../');
var request = require('supertest');
describe('hidden properties', function() {
beforeEach(function(done) {
const app = this.app = loopback();
const Product = this.Product = loopback.PersistedModel.extend(
var app = this.app = loopback();
var Product = this.Product = loopback.PersistedModel.extend(
'product',
{},
{hidden: ['secret']},
{hidden: ['secret']}
);
Product.attachTo(loopback.memory());
const Category = this.Category = loopback.PersistedModel.extend('category');
var Category = this.Category = loopback.PersistedModel.extend('category');
Category.attachTo(loopback.memory());
Category.hasMany(Product);
@ -37,7 +37,7 @@ describe('hidden properties', function() {
});
afterEach(function(done) {
const Product = this.Product;
var Product = this.Product;
this.Category.destroyAll(function() {
Product.destroyAll(done);
});
@ -51,7 +51,7 @@ describe('hidden properties', function() {
.end(function(err, res) {
if (err) return done(err);
const product = res.body[0];
var product = res.body[0];
assert.equal(product.secret, undefined);
done();
@ -59,7 +59,7 @@ describe('hidden properties', function() {
});
it('should hide a property of nested models', function(done) {
const app = this.app;
var app = this.app;
request(app)
.get('/categories?filter[include]=products')
.expect('Content-Type', /json/)
@ -67,8 +67,8 @@ describe('hidden properties', function() {
.end(function(err, res) {
if (err) return done(err);
const category = res.body[0];
const product = category.products[0];
var category = res.body[0];
var product = category.products[0];
assert.equal(product.secret, undefined);
done();

View File

@ -1,18 +1,18 @@
// Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Copyright IBM Corp. 2014,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const expect = require('./helpers/expect');
const loopback = require('../');
const net = require('net');
var expect = require('./helpers/expect');
var loopback = require('../');
var net = require('net');
describe('loopback application', function() {
it('pauses request stream during authentication', function(done) {
// This test reproduces the issue reported in
// https://github.com/strongloop/loopback-storage-service/issues/7
const app = loopback();
var app = loopback();
setupAppWithStreamingMethod();
app.listen(0, function() {
@ -29,7 +29,7 @@ describe('loopback application', function() {
expect(res).to.match(/\nX$/);
done();
},
}
);
});
@ -37,7 +37,7 @@ describe('loopback application', function() {
app.dataSource('db', {
connector: loopback.Memory,
});
const db = app.datasources.db;
var db = app.datasources.db;
loopback.User.attachTo(db);
loopback.AccessToken.attachTo(db);
@ -45,10 +45,10 @@ describe('loopback application', function() {
loopback.ACL.attachTo(db);
loopback.User.hasMany(loopback.AccessToken, {as: 'accessTokens'});
const Streamer = app.registry.createModel('Streamer');
var Streamer = app.registry.createModel('Streamer');
app.model(Streamer, {dataSource: 'db'});
Streamer.read = function(req, res, cb) {
let body = new Buffer(0);
var body = new Buffer(0);
req.on('data', function(chunk) {
body += chunk;
});
@ -75,8 +75,8 @@ describe('loopback application', function() {
}
function sendHttpRequestInOnePacket(port, reqString, cb) {
const socket = net.createConnection(port);
let response = new Buffer(0);
var socket = net.createConnection(port);
var response = new Buffer(0);
socket.on('data', function(chunk) {
response += chunk;

View File

@ -1,39 +1,14 @@
// Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Copyright IBM Corp. 2014,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const isDocker = require('is-docker');
const which = require('which');
// Karma configuration
// http://karma-runner.github.io/0.12/config/configuration-file.html
'use strict';
module.exports = function(config) {
// see https://github.com/docker/for-linux/issues/496
const disableChromeSandbox = isDocker() && !process.env.TRAVIS;
if (disableChromeSandbox) {
console.log('!! Disabling Chrome sandbox to support un-privileged Docker !!');
}
const hasChromium =
which.sync('chromium-browser', {nothrow: true}) ||
which.sync('chromium', {nothrow: true});
config.set({
customLaunchers: {
ChromeDocker: {
// cis-jenkins build server does not provide Chrome, only Chromium
base: hasChromium ? 'ChromiumHeadless' : 'ChromeHeadless',
// We must disable the Chrome sandbox when running Chrome inside Docker
// (Chrome's sandbox needs more permissions than Docker allows by default)
// See https://github.com/docker/for-linux/issues/496
flags: disableChromeSandbox ? ['--no-sandbox'] : [],
},
},
// enable / disable watching file and executing tests whenever any file changes
autoWatch: true,
@ -89,6 +64,7 @@ module.exports = function(config) {
'karma-browserify',
'karma-es6-shim',
'karma-mocha',
'karma-phantomjs-launcher',
'karma-chrome-launcher',
'karma-junit-reporter',
],
@ -128,18 +104,27 @@ module.exports = function(config) {
'superagent',
'supertest',
],
packageFilter: function(pkg, dir) {
// async@3 (used e.g. by loopback-connector) is specifying custom
// browserify config, in particular it wants to apply transformation
// `babelify`. We don't have `babelify` installed because we are
// testing using latest Chrome and thus don't need any transpilation.
// Let's remove the browserify config from the package and force
// browserify to use our config instead.
if (pkg.name === 'async') {
delete pkg.browserify;
}
return pkg;
},
transform: [
['babelify', {
presets: [
['es2015', {
// Disable transform-es2015-modules-commonjs which adds
// "use strict" to all files, even those that don't work
// in strict mode
// (e.g. chai, loopback-datasource-juggler, etc.)
modules: false,
}],
],
// By default, browserify does not transform node_modules
// As a result, our dependencies like strong-remoting and juggler
// are kept in original ES6 form that does not work in PhantomJS
global: true,
// Prevent SyntaxError in strong-task-emitter:
// strong-task-emitter/lib/task.js (83:4):
// arguments is a reserved word in strict mode
ignore: /node_modules\/(strong-task-emitter)\//,
}],
],
debug: true,
// noParse: ['jquery'],
watch: true,

View File

@ -1,18 +1,18 @@
// Copyright IBM Corp. 2016,2019. All Rights Reserved.
// Copyright IBM Corp. 2016,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const expect = require('./helpers/expect');
const http = require('http');
const loopback = require('..');
const supertest = require('supertest');
var expect = require('./helpers/expect');
var http = require('http');
var loopback = require('..');
var supertest = require('supertest');
const AN_OBJECT_VALUE = {name: 'an-object'};
var AN_OBJECT_VALUE = {name: 'an-object'};
describe('KeyValueModel', function() {
let request, app, CacheItem;
var request, app, CacheItem;
beforeEach(setupAppAndCacheItem);
describe('REST API', function() {
@ -156,7 +156,7 @@ describe('KeyValueModel', function() {
app.model(CacheItem, {dataSource: 'kv'});
}
let _server, _requestHandler; // eslint-disable-line one-var
var _server, _requestHandler; // eslint-disable-line one-var
function setupSharedHttpServer(done) {
_server = http.createServer(function(req, res) {
app(req, res);

View File

@ -1,20 +1,20 @@
// Copyright IBM Corp. 2013,2019. All Rights Reserved.
// Copyright IBM Corp. 2013,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const it = require('./util/it');
const describe = require('./util/describe');
const Domain = require('domain');
const EventEmitter = require('events').EventEmitter;
const loopback = require('../');
const expect = require('./helpers/expect');
const assert = require('assert');
var it = require('./util/it');
var describe = require('./util/describe');
var Domain = require('domain');
var EventEmitter = require('events').EventEmitter;
var loopback = require('../');
var expect = require('./helpers/expect');
var assert = require('assert');
describe('loopback', function() {
let nameCounter = 0;
let uniqueModelName;
var nameCounter = 0;
var uniqueModelName;
beforeEach(function() {
uniqueModelName = 'TestModel-' + (++nameCounter);
@ -27,7 +27,7 @@ describe('loopback', function() {
});
it.onServer('includes `faviconFile`', function() {
const file = loopback.faviconFile;
var file = loopback.faviconFile;
expect(file, 'faviconFile').to.not.equal(undefined);
expect(require('fs').existsSync(loopback.faviconFile), 'file exists')
.to.equal(true);
@ -38,7 +38,7 @@ describe('loopback', function() {
});
it.onServer('exports all expected properties', function() {
const EXPECTED = [
var EXPECTED = [
'ACL',
'AccessToken',
'Application',
@ -98,7 +98,7 @@ describe('loopback', function() {
'version',
];
const actual = Object.getOwnPropertyNames(loopback);
var actual = Object.getOwnPropertyNames(loopback);
actual.sort();
expect(actual).to.include.members(EXPECTED);
});
@ -106,17 +106,17 @@ describe('loopback', function() {
describe('loopback(options)', function() {
it('supports localRegistry:true', function() {
const app = loopback({localRegistry: true});
var app = loopback({localRegistry: true});
expect(app.registry).to.not.equal(loopback.registry);
});
it('does not load builtin models into the local registry', function() {
const app = loopback({localRegistry: true});
var app = loopback({localRegistry: true});
expect(app.registry.findModel('User')).to.equal(undefined);
});
it('supports loadBuiltinModels:true', function() {
const app = loopback({localRegistry: true, loadBuiltinModels: true});
var app = loopback({localRegistry: true, loadBuiltinModels: true});
expect(app.registry.findModel('User'))
.to.have.property('modelName', 'User');
});
@ -124,7 +124,7 @@ describe('loopback', function() {
describe('loopback.createDataSource(options)', function() {
it('Create a data source with a connector.', function() {
const dataSource = loopback.createDataSource({
var dataSource = loopback.createDataSource({
connector: loopback.Memory,
});
assert(dataSource.connector);
@ -133,24 +133,24 @@ describe('loopback', function() {
describe('data source created by loopback', function() {
it('should create model extending Model by default', function() {
const dataSource = loopback.createDataSource({
var dataSource = loopback.createDataSource({
connector: loopback.Memory,
});
const m1 = dataSource.createModel('m1', {});
var m1 = dataSource.createModel('m1', {});
assert(m1.prototype instanceof loopback.Model);
});
});
describe('model created by loopback', function() {
it('should extend from Model by default', function() {
const m1 = loopback.createModel('m1', {});
var m1 = loopback.createModel('m1', {});
assert(m1.prototype instanceof loopback.Model);
});
});
describe('loopback.remoteMethod(Model, fn, [options]);', function() {
it('Setup a remote method.', function() {
const Product = loopback.createModel('product', {price: Number});
var Product = loopback.createModel('product', {price: Number});
Product.stats = function(fn) {
// ...
@ -161,7 +161,7 @@ describe('loopback', function() {
{
returns: {arg: 'stats', type: 'array'},
http: {path: '/info', verb: 'get'},
},
}
);
assert.equal(Product.stats.returns.arg, 'stats');
@ -175,12 +175,12 @@ describe('loopback', function() {
describe('loopback.createModel(name, properties, options)', function() {
describe('options.base', function() {
it('should extend from options.base', function() {
const MyModel = loopback.createModel('MyModel', {}, {
var MyModel = loopback.createModel('MyModel', {}, {
foo: {
bar: 'bat',
},
});
const MyCustomModel = loopback.createModel('MyCustomModel', {}, {
var MyCustomModel = loopback.createModel('MyCustomModel', {}, {
base: 'MyModel',
foo: {
bat: 'baz',
@ -194,12 +194,12 @@ describe('loopback', function() {
describe('loopback.getModel and getModelByType', function() {
it('should be able to get model by name', function() {
const MyModel = loopback.createModel('MyModel', {}, {
var MyModel = loopback.createModel('MyModel', {}, {
foo: {
bar: 'bat',
},
});
const MyCustomModel = loopback.createModel('MyCustomModel', {}, {
var MyCustomModel = loopback.createModel('MyCustomModel', {}, {
base: 'MyModel',
foo: {
bat: 'baz',
@ -211,12 +211,12 @@ describe('loopback', function() {
assert(loopback.getModel(MyModel) === MyModel);
});
it('should be able to get model by type', function() {
const MyModel = loopback.createModel('MyModel', {}, {
var MyModel = loopback.createModel('MyModel', {}, {
foo: {
bar: 'bat',
},
});
const MyCustomModel = loopback.createModel('MyCustomModel', {}, {
var MyCustomModel = loopback.createModel('MyCustomModel', {}, {
base: 'MyModel',
foo: {
bat: 'baz',
@ -233,7 +233,7 @@ describe('loopback', function() {
});
it('configures remote methods', function() {
const TestModel = loopback.createModel(uniqueModelName, {}, {
var TestModel = loopback.createModel(uniqueModelName, {}, {
methods: {
staticMethod: {
isStatic: true,
@ -246,7 +246,7 @@ describe('loopback', function() {
},
});
const methodNames = TestModel.sharedClass.methods().map(function(m) {
var methodNames = TestModel.sharedClass.methods().map(function(m) {
return m.stringName.replace(/^[^.]+\./, ''); // drop the class name
});
@ -259,7 +259,7 @@ describe('loopback', function() {
describe('loopback.createModel(config)', function() {
it('creates the model', function() {
const model = loopback.createModel({
var model = loopback.createModel({
name: uniqueModelName,
});
@ -267,7 +267,7 @@ describe('loopback', function() {
});
it('interprets extra first-level keys as options', function() {
const model = loopback.createModel({
var model = loopback.createModel({
name: uniqueModelName,
base: 'User',
});
@ -276,7 +276,7 @@ describe('loopback', function() {
});
it('prefers config.options.key over config.key', function() {
const model = loopback.createModel({
var model = loopback.createModel({
name: uniqueModelName,
base: 'User',
options: {
@ -290,7 +290,7 @@ describe('loopback', function() {
describe('loopback.configureModel(ModelCtor, config)', function() {
it('adds new relations', function() {
const model = loopback.Model.extend(uniqueModelName);
var model = loopback.Model.extend(uniqueModelName);
loopback.configureModel(model, {
dataSource: null,
@ -306,7 +306,7 @@ describe('loopback', function() {
});
it('updates existing relations', function() {
const model = loopback.Model.extend(uniqueModelName, {}, {
var model = loopback.Model.extend(uniqueModelName, {}, {
relations: {
owner: {
type: 'belongsTo',
@ -331,8 +331,8 @@ describe('loopback', function() {
});
it('updates relations before attaching to a dataSource', function() {
const db = loopback.createDataSource({connector: loopback.Memory});
const model = loopback.Model.extend(uniqueModelName);
var db = loopback.createDataSource({connector: loopback.Memory});
var model = loopback.Model.extend(uniqueModelName);
// This test used to work because User model was already attached
// by other tests via `loopback.autoAttach()`
@ -352,13 +352,13 @@ describe('loopback', function() {
},
});
const owner = model.prototype.owner;
var owner = model.prototype.owner;
expect(owner, 'model.prototype.owner').to.be.a('function');
expect(owner._targetClass).to.equal('User');
});
it('adds new acls', function() {
const model = loopback.Model.extend(uniqueModelName, {}, {
var model = loopback.Model.extend(uniqueModelName, {}, {
acls: [
{
property: 'find',
@ -402,7 +402,7 @@ describe('loopback', function() {
});
it('updates existing acls', function() {
const model = loopback.Model.extend(uniqueModelName, {}, {
var model = loopback.Model.extend(uniqueModelName, {}, {
acls: [
{
property: 'find',
@ -439,12 +439,12 @@ describe('loopback', function() {
});
it('updates existing settings', function() {
const model = loopback.Model.extend(uniqueModelName, {}, {
var model = loopback.Model.extend(uniqueModelName, {}, {
ttl: 10,
emailVerificationRequired: false,
});
const baseName = model.settings.base.name;
var baseName = model.settings.base.name;
loopback.configureModel(model, {
dataSource: null,
@ -465,7 +465,7 @@ describe('loopback', function() {
});
it('configures remote methods', function() {
const TestModel = loopback.createModel(uniqueModelName);
var TestModel = loopback.createModel(uniqueModelName);
loopback.configureModel(TestModel, {
dataSource: null,
methods: {
@ -480,7 +480,7 @@ describe('loopback', function() {
},
});
const methodNames = TestModel.sharedClass.methods().map(function(m) {
var methodNames = TestModel.sharedClass.methods().map(function(m) {
return m.stringName.replace(/^[^.]+\./, ''); // drop the class name
});
@ -493,14 +493,14 @@ describe('loopback', function() {
describe('loopback object', function() {
it('inherits properties from express', function() {
const express = require('express');
for (const i in express) {
var express = require('express');
for (var i in express) {
expect(loopback).to.have.property(i, express[i]);
}
});
it('exports all built-in models', function() {
const expectedModelNames = [
var expectedModelNames = [
'Email',
'User',
'Application',
@ -530,7 +530,7 @@ describe('loopback', function() {
}
it('treats method names that don\'t start with "prototype." as "isStatic:true"', function() {
const TestModel = loopback.createModel(uniqueModelName);
var TestModel = loopback.createModel(uniqueModelName);
loopback.configureModel(TestModel, {
dataSource: null,
methods: {
@ -540,13 +540,13 @@ describe('loopback', function() {
},
});
const methodNames = getAllMethodNamesWithoutClassName(TestModel);
var methodNames = getAllMethodNamesWithoutClassName(TestModel);
expect(methodNames).to.include('staticMethod');
});
it('treats method names starting with "prototype." as "isStatic:false"', function() {
const TestModel = loopback.createModel(uniqueModelName);
var TestModel = loopback.createModel(uniqueModelName);
loopback.configureModel(TestModel, {
dataSource: null,
methods: {
@ -556,15 +556,13 @@ describe('loopback', function() {
},
});
const methodNames = getAllMethodNamesWithoutClassName(TestModel);
var methodNames = getAllMethodNamesWithoutClassName(TestModel);
expect(methodNames).to.include('prototype.instanceMethod');
});
// Skip this test in browsers because strong-globalize is not removing
// `{{` and `}}` control characters from the string.
it.onServer('throws when "isStatic:true" and method name starts with "prototype."', function() {
const TestModel = loopback.createModel(uniqueModelName);
it('throws an error when "isStatic:true" and method name starts with "prototype."', function() {
var TestModel = loopback.createModel(uniqueModelName);
expect(function() {
loopback.configureModel(TestModel, {
dataSource: null,
@ -575,12 +573,12 @@ describe('loopback', function() {
},
},
});
}).to.throw(Error, 'Remoting metadata for ' + TestModel.modelName +
'.prototype.instanceMethod "isStatic" does not match new method name-based style.');
}).to.throw(Error, new Error('Remoting metadata for' + TestModel.modelName +
' "isStatic" does not match new method name-based style.'));
});
it('use "isStatic:true" if method name does not start with "prototype."', function() {
const TestModel = loopback.createModel(uniqueModelName);
var TestModel = loopback.createModel(uniqueModelName);
loopback.configureModel(TestModel, {
dataSource: null,
methods: {
@ -591,13 +589,13 @@ describe('loopback', function() {
},
});
const methodNames = getAllMethodNamesWithoutClassName(TestModel);
var methodNames = getAllMethodNamesWithoutClassName(TestModel);
expect(methodNames).to.include('staticMethod');
});
it('use "isStatic:false" if method name starts with "prototype."', function() {
const TestModel = loopback.createModel(uniqueModelName);
var TestModel = loopback.createModel(uniqueModelName);
loopback.configureModel(TestModel, {
dataSource: null,
methods: {
@ -608,19 +606,19 @@ describe('loopback', function() {
},
});
const methodNames = getAllMethodNamesWithoutClassName(TestModel);
var methodNames = getAllMethodNamesWithoutClassName(TestModel);
expect(methodNames).to.include('prototype.instanceMethod');
});
});
describe('Remote method inheritance', function() {
let app;
var app;
beforeEach(setupLoopback);
it('inherits remote methods defined via createModel', function() {
const Base = app.registry.createModel('Base', {}, {
var Base = app.registry.createModel('Base', {}, {
methods: {
greet: {
http: {path: '/greet'},
@ -628,7 +626,7 @@ describe('loopback', function() {
},
});
const MyCustomModel = app.registry.createModel('MyCustomModel', {}, {
var MyCustomModel = app.registry.createModel('MyCustomModel', {}, {
base: 'Base',
methods: {
hello: {
@ -636,14 +634,14 @@ describe('loopback', function() {
},
},
});
const methodNames = getAllMethodNamesWithoutClassName(MyCustomModel);
var methodNames = getAllMethodNamesWithoutClassName(MyCustomModel);
expect(methodNames).to.include('greet');
expect(methodNames).to.include('hello');
});
it('same remote method with different metadata should override parent', function() {
const Base = app.registry.createModel('Base', {}, {
var Base = app.registry.createModel('Base', {}, {
methods: {
greet: {
http: {path: '/greet'},
@ -651,7 +649,7 @@ describe('loopback', function() {
},
});
const MyCustomModel = app.registry.createModel('MyCustomModel', {}, {
var MyCustomModel = app.registry.createModel('MyCustomModel', {}, {
base: 'Base',
methods: {
greet: {
@ -659,9 +657,9 @@ describe('loopback', function() {
},
},
});
const methodNames = getAllMethodNamesWithoutClassName(MyCustomModel);
const baseMethod = Base.sharedClass.findMethodByName('greet');
const customMethod = MyCustomModel.sharedClass.findMethodByName('greet');
var methodNames = getAllMethodNamesWithoutClassName(MyCustomModel);
var baseMethod = Base.sharedClass.findMethodByName('greet');
var customMethod = MyCustomModel.sharedClass.findMethodByName('greet');
// Base Method
expect(baseMethod.http).to.eql({path: '/greet'});
@ -676,7 +674,7 @@ describe('loopback', function() {
});
it('does not inherit remote methods defined via configureModel', function() {
const Base = app.registry.createModel('Base');
var Base = app.registry.createModel('Base');
app.registry.configureModel(Base, {
dataSource: null,
methods: {
@ -686,7 +684,7 @@ describe('loopback', function() {
},
});
const MyCustomModel = app.registry.createModel('MyCustomModel', {}, {
var MyCustomModel = app.registry.createModel('MyCustomModel', {}, {
base: 'Base',
methods: {
hello: {
@ -694,7 +692,7 @@ describe('loopback', function() {
},
},
});
const methodNames = getAllMethodNamesWithoutClassName(MyCustomModel);
var methodNames = getAllMethodNamesWithoutClassName(MyCustomModel);
expect(methodNames).to.not.include('greet');
expect(methodNames).to.include('hello');
@ -702,8 +700,8 @@ describe('loopback', function() {
it('does not inherit remote methods defined via configureModel after child model ' +
'was created', function() {
const Base = app.registry.createModel('Base');
const MyCustomModel = app.registry.createModel('MyCustomModel', {}, {
var Base = app.registry.createModel('Base');
var MyCustomModel = app.registry.createModel('MyCustomModel', {}, {
base: 'Base',
});
@ -724,8 +722,8 @@ describe('loopback', function() {
},
},
});
const baseMethodNames = getAllMethodNamesWithoutClassName(Base);
const methodNames = getAllMethodNamesWithoutClassName(MyCustomModel);
var baseMethodNames = getAllMethodNamesWithoutClassName(Base);
var methodNames = getAllMethodNamesWithoutClassName(MyCustomModel);
expect(baseMethodNames).to.include('greet');
expect(methodNames).to.not.include('greet');
@ -744,12 +742,12 @@ describe('loopback', function() {
});
describe('Hiding shared methods', function() {
let app;
var app;
beforeEach(setupLoopback);
it('hides remote methods using fixed method names', function() {
const TestModel = app.registry.createModel(uniqueModelName);
var TestModel = app.registry.createModel(uniqueModelName);
app.model(TestModel, {
dataSource: null,
methods: {
@ -767,7 +765,7 @@ describe('loopback', function() {
},
});
const publicMethods = getSharedMethods(TestModel);
var publicMethods = getSharedMethods(TestModel);
expect(publicMethods).not.to.include.members([
'staticMethod',
@ -775,7 +773,7 @@ describe('loopback', function() {
});
it('hides remote methods using a glob pattern', function() {
const TestModel = app.registry.createModel(uniqueModelName);
var TestModel = app.registry.createModel(uniqueModelName);
app.model(TestModel, {
dataSource: null,
methods: {
@ -797,7 +795,7 @@ describe('loopback', function() {
},
});
const publicMethods = getSharedMethods(TestModel);
var publicMethods = getSharedMethods(TestModel);
expect(publicMethods).to.include.members([
'staticMethod',
@ -808,7 +806,7 @@ describe('loopback', function() {
});
it('hides all remote methods using *', function() {
const TestModel = app.registry.createModel(uniqueModelName);
var TestModel = app.registry.createModel(uniqueModelName);
app.model(TestModel, {
dataSource: null,
methods: {
@ -830,7 +828,7 @@ describe('loopback', function() {
},
});
const publicMethods = getSharedMethods(TestModel);
var publicMethods = getSharedMethods(TestModel);
expect(publicMethods).to.be.empty();
});

View File

@ -1,17 +1,17 @@
// Copyright IBM Corp. 2013,2019. All Rights Reserved.
// Copyright IBM Corp. 2013,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const assert = require('assert');
const loopback = require('../');
var assert = require('assert');
var loopback = require('../');
describe('Memory Connector', function() {
it('Create a model using the memory connector', function(done) {
// use the built in memory function
// to create a memory data source
let memory = loopback.memory();
var memory = loopback.memory();
// or create it using the standard
// data source creation api
@ -21,12 +21,12 @@ describe('Memory Connector', function() {
// create a model using the
// memory data source
const properties = {
var properties = {
name: String,
price: Number,
};
const Product = memory.createModel('product', properties);
var Product = memory.createModel('product', properties);
Product.create([
{name: 'apple', price: 0.79},

View File

@ -1,15 +1,15 @@
// Copyright IBM Corp. 2013,2019. All Rights Reserved.
// Copyright IBM Corp. 2013,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const loopback = require(('../'));
const assert = require('assert');
const Application = loopback.Application;
var loopback = require(('../'));
var assert = require('assert');
var Application = loopback.Application;
describe('Application', function() {
let registeredApp = null;
var registeredApp = null;
before(function attachToMemory() {
Application.attachTo(loopback.memory());
@ -18,7 +18,7 @@ describe('Application', function() {
it('honors `application.register` - callback variant', function(done) {
Application.register('rfeng', 'MyTestApp',
{description: 'My test application'}, function(err, result) {
const app = result;
var app = result;
assert.equal(app.owner, 'rfeng');
assert.equal(app.name, 'MyTestApp');
assert.equal(app.description, 'My test application');
@ -31,7 +31,7 @@ describe('Application', function() {
Application.register('rfeng', 'MyTestApp',
{description: 'My test application'})
.then(function(result) {
const app = result;
var app = result;
assert.equal(app.owner, 'rfeng');
assert.equal(app.name, 'MyTestApp');
assert.equal(app.description, 'My test application');
@ -47,7 +47,7 @@ describe('Application', function() {
Application.create({owner: 'rfeng',
name: 'MyApp1',
description: 'My first mobile application'}, function(err, result) {
const app = result;
var app = result;
assert.equal(app.owner, 'rfeng');
assert.equal(app.name, 'MyApp1');
assert.equal(app.description, 'My first mobile application');
@ -90,7 +90,7 @@ describe('Application', function() {
},
}},
function(err, result) {
const app = result;
var app = result;
assert.deepEqual(app.pushSettings.toObject(), {
apns: {
production: false,
@ -119,7 +119,7 @@ describe('Application', function() {
beforeEach(function(done) {
Application.register('rfeng', 'MyApp2',
{description: 'My second mobile application'}, function(err, result) {
const app = result;
var app = result;
assert.equal(app.owner, 'rfeng');
assert.equal(app.name, 'MyApp2');
assert.equal(app.description, 'My second mobile application');
@ -138,7 +138,7 @@ describe('Application', function() {
it('Reset keys', function(done) {
Application.resetKeys(registeredApp.id, function(err, result) {
const app = result;
var app = result;
assert.equal(app.owner, 'rfeng');
assert.equal(app.name, 'MyApp2');
assert.equal(app.description, 'My second mobile application');
@ -165,7 +165,7 @@ describe('Application', function() {
it('Reset keys - promise variant', function(done) {
Application.resetKeys(registeredApp.id)
.then(function(result) {
const app = result;
var app = result;
assert.equal(app.owner, 'rfeng');
assert.equal(app.name, 'MyApp2');
assert.equal(app.description, 'My second mobile application');
@ -194,7 +194,7 @@ describe('Application', function() {
it('Reset keys without create a new instance', function(done) {
Application.resetKeys(registeredApp.id, function(err, result) {
const app = result;
var app = result;
assert(app.id);
assert(app.id === registeredApp.id);
registeredApp = app;
@ -206,7 +206,7 @@ describe('Application', function() {
it('Reset keys without create a new instance - promise variant', function(done) {
Application.resetKeys(registeredApp.id)
.then(function(result) {
const app = result;
var app = result;
assert(app.id);
assert(app.id === registeredApp.id);
registeredApp = app;
@ -307,12 +307,12 @@ describe('Application', function() {
describe('Application subclass', function() {
it('should use subclass model name', function(done) {
const MyApp = Application.extend('MyApp');
const ds = loopback.createDataSource({connector: loopback.Memory});
var MyApp = Application.extend('MyApp');
var ds = loopback.createDataSource({connector: loopback.Memory});
MyApp.attachTo(ds);
MyApp.register('rfeng', 'MyApp123',
{description: 'My 123 mobile application'}, function(err, result) {
const app = result;
var app = result;
assert.equal(app.owner, 'rfeng');
assert.equal(app.name, 'MyApp123');
assert.equal(app.description, 'My 123 mobile application');

View File

@ -1,21 +1,21 @@
// Copyright IBM Corp. 2013,2019. All Rights Reserved.
// Copyright IBM Corp. 2013,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const assert = require('assert');
const async = require('async');
const describe = require('./util/describe');
const loopback = require('../');
const ACL = loopback.ACL;
const defineModelTestsWithDataSource = require('./util/model-tests');
const PersistedModel = loopback.PersistedModel;
const Promise = require('bluebird');
const TaskEmitter = require('strong-task-emitter');
const request = require('supertest');
var assert = require('assert');
var async = require('async');
var describe = require('./util/describe');
var loopback = require('../');
var ACL = loopback.ACL;
var defineModelTestsWithDataSource = require('./util/model-tests');
var PersistedModel = loopback.PersistedModel;
var Promise = require('bluebird');
var TaskEmitter = require('strong-task-emitter');
var request = require('supertest');
const expect = require('./helpers/expect');
var expect = require('./helpers/expect');
describe('Model / PersistedModel', function() {
defineModelTestsWithDataSource({
@ -26,7 +26,7 @@ describe('Model / PersistedModel', function() {
describe('Model.validatesUniquenessOf(property, options)', function() {
it('Ensure the value for `property` is unique', function(done) {
const User = PersistedModel.extend('ValidatedUser', {
var User = PersistedModel.extend('ValidatedUser', {
'first': String,
'last': String,
'age': Number,
@ -36,7 +36,7 @@ describe('Model / PersistedModel', function() {
'email': String,
});
const dataSource = loopback.createDataSource({
var dataSource = loopback.createDataSource({
connector: loopback.Memory,
});
@ -44,8 +44,8 @@ describe('Model / PersistedModel', function() {
User.validatesUniquenessOf('email', {message: 'email is not unique'});
const joe = new User({email: 'joe@joe.com'});
const joe2 = new User({email: 'joe@joe.com'});
var joe = new User({email: 'joe@joe.com'});
var joe2 = new User({email: 'joe@joe.com'});
joe.save(function() {
joe2.save(function(err) {
@ -60,8 +60,8 @@ describe('Model / PersistedModel', function() {
describe('Model.attachTo(dataSource)', function() {
it('Attach a model to a [DataSource](#data-source)', function() {
const MyModel = loopback.createModel('my-model', {name: String});
const dataSource = loopback.createDataSource({
var MyModel = loopback.createModel('my-model', {name: String});
var dataSource = loopback.createDataSource({
connector: loopback.Memory,
});
@ -76,7 +76,7 @@ describe('Model / PersistedModel', function() {
});
describe.onServer('Remote Methods', function() {
let User, Post, dataSource, app;
var User, Post, dataSource, app;
beforeEach(function() {
app = loopback({localRegistry: true, loadBuiltinModels: true});
@ -132,7 +132,7 @@ describe.onServer('Remote Methods', function() {
describe('Model.create(data, callback)', function() {
it('creates model', function(done) {
const anObject = {first: 'June'};
var anObject = {first: 'June'};
request(app)
.post('/users')
// sends an object
@ -149,7 +149,7 @@ describe.onServer('Remote Methods', function() {
// batch create must be tested with a remote request because there are
// coercion being done on strong-remoting side
it('creates array of models', function(done) {
const arrayOfObjects = [
var arrayOfObjects = [
{first: 'John'}, {first: 'Jane'},
];
request(app)
@ -161,8 +161,8 @@ describe.onServer('Remote Methods', function() {
.end(function(err, res) {
if (err) return done(err);
expect(res.body.length).to.eql(2);
expect(res.body).to.have.nested.property('[0].first', 'John');
expect(res.body).to.have.nested.property('[1].first', 'Jane');
expect(res.body).to.have.deep.property('[0].first', 'John');
expect(res.body).to.have.deep.property('[1].first', 'Jane');
done();
});
});
@ -170,7 +170,7 @@ describe.onServer('Remote Methods', function() {
it('creates related models', function(done) {
User.create({first: 'Bob'}, function(err, res) {
expect(res).to.have.property('id');
const aPost = {title: 'A story', content: 'Once upon a time'};
var aPost = {title: 'A story', content: 'Once upon a time'};
request(app)
.post('/users/' + res.id + '/posts')
.send(aPost)
@ -189,7 +189,7 @@ describe.onServer('Remote Methods', function() {
it('creates array of hasMany models', function(done) {
User.create({first: 'Bob'}, function(err, res) {
expect(res).to.have.property('id');
const twoPosts = [
var twoPosts = [
{title: 'One story', content: 'Content #1'},
{title: 'Two story', content: 'Content #2'},
];
@ -201,21 +201,21 @@ describe.onServer('Remote Methods', function() {
.end(function(err, result) {
if (err) return done(err);
expect(result.body.length).to.eql(2);
expect(result.body).to.have.nested.property('[0].title', 'One story');
expect(result.body).to.have.nested.property('[1].title', 'Two story');
expect(result.body).to.have.deep.property('[0].title', 'One story');
expect(result.body).to.have.deep.property('[1].title', 'Two story');
done();
});
});
});
it('rejects array of obj input for hasOne relation', function(done) {
const Friend = app.registry.createModel('friend', {name: String});
var Friend = app.registry.createModel('friend', {name: String});
app.model(Friend, {dataSource: 'db'});
User.hasOne(Friend);
User.create({first: 'Bob'}, function(err, res) {
expect(res).to.have.property('id');
const twoFriends = [
var twoFriends = [
{name: 'bob'},
{name: 'rob'},
];
@ -226,7 +226,7 @@ describe.onServer('Remote Methods', function() {
.expect(400)
.end(function(err, result) {
if (err) return done(err);
const resError = result.body.error;
var resError = result.body.error;
expect(resError.message).to.match(/value(.*?)not(.*?)object(\.?)/i);
done();
});
@ -258,14 +258,14 @@ describe.onServer('Remote Methods', function() {
describe('Model.upsertWithWhere(where, data, callback)', function() {
it('Updates when a Model instance is retreived from data source', function(done) {
const taskEmitter = new TaskEmitter();
var taskEmitter = new TaskEmitter();
taskEmitter
.task(User, 'create', {first: 'jill', second: 'pill'})
.task(User, 'create', {first: 'bob', second: 'sob'})
.on('done', function() {
User.upsertWithWhere({second: 'pill'}, {second: 'jones'}, function(err, user) {
if (err) return done(err);
const id = user.id;
var id = user.id;
User.findById(id, function(err, user) {
if (err) return done(err);
assert.equal(user.second, 'jones');
@ -276,13 +276,13 @@ describe.onServer('Remote Methods', function() {
});
it('Creates when no Model instance is retreived from data source', function(done) {
const taskEmitter = new TaskEmitter();
var taskEmitter = new TaskEmitter();
taskEmitter
.task(User, 'create', {first: 'simon', second: 'somers'})
.on('done', function() {
User.upsertWithWhere({first: 'somers'}, {first: 'Simon'}, function(err, user) {
if (err) return done(err);
const id = user.id;
var id = user.id;
User.findById(id, function(err, user) {
if (err) return done(err);
assert.equal(user.first, 'Simon');
@ -315,7 +315,7 @@ describe.onServer('Remote Methods', function() {
.end(function(err, res) {
if (err) return done(err);
const errorResponse = res.body.error;
var errorResponse = res.body.error;
assert(errorResponse);
assert.equal(errorResponse.code, 'MODEL_NOT_FOUND');
@ -332,7 +332,7 @@ describe.onServer('Remote Methods', function() {
.end(function(err, res) {
if (err) return done(err);
const userId = res.body.id;
var userId = res.body.id;
assert(userId);
request(app)
.get('/users/' + userId + '?filter[fields]=first')
@ -358,7 +358,7 @@ describe.onServer('Remote Methods', function() {
.end(function(err, res) {
if (err) return done(err);
const userId = res.body.id;
var userId = res.body.id;
assert(userId);
request(app)
.post('/users/' + userId + '/posts')
@ -368,7 +368,7 @@ describe.onServer('Remote Methods', function() {
.end(function(err, res) {
if (err) return done(err);
const post = res.body;
var post = res.body;
request(app)
.get('/users/' + userId + '?filter[include]=posts')
.expect('Content-Type', /json/)
@ -389,7 +389,7 @@ describe.onServer('Remote Methods', function() {
describe('Model.beforeRemote(name, fn)', function() {
it('Run a function before a remote method is called by a client', function(done) {
let hookCalled = false;
var hookCalled = false;
User.beforeRemote('create', function(ctx, user, next) {
hookCalled = true;
@ -413,7 +413,7 @@ describe.onServer('Remote Methods', function() {
});
it('Does not stop the hook chain after returning a promise', function(done) {
const hooksCalled = [];
var hooksCalled = [];
User.beforeRemote('create', function() {
hooksCalled.push('first');
@ -441,8 +441,8 @@ describe.onServer('Remote Methods', function() {
describe('Model.afterRemote(name, fn)', function() {
it('Run a function after a remote method is called by a client', function(done) {
let beforeCalled = false;
let afterCalled = false;
var beforeCalled = false;
var afterCalled = false;
User.beforeRemote('create', function(ctx, user, next) {
assert(!afterCalled);
@ -476,7 +476,7 @@ describe.onServer('Remote Methods', function() {
describe('Model.afterRemoteError(name, fn)', function() {
it('runs the function when method fails', function(done) {
let actualError = 'hook not called';
var actualError = 'hook not called';
User.afterRemoteError('login', function(ctx, next) {
actualError = ctx.error;
@ -498,7 +498,7 @@ describe.onServer('Remote Methods', function() {
describe('Remote Method invoking context', function() {
describe('ctx.req', function() {
it('The express ServerRequest object', function(done) {
let hookCalled = false;
var hookCalled = false;
User.beforeRemote('create', function(ctx, user, next) {
hookCalled = true;
@ -530,7 +530,7 @@ describe.onServer('Remote Methods', function() {
describe('ctx.res', function() {
it('The express ServerResponse object', function(done) {
let hookCalled = false;
var hookCalled = false;
User.beforeRemote('create', function(ctx, user, next) {
hookCalled = true;
@ -563,15 +563,15 @@ describe.onServer('Remote Methods', function() {
describe('Model.hasMany(Model)', function() {
it('Define a one to many relationship', function(done) {
const Book = dataSource.createModel('book', {title: String, author: String});
const Chapter = dataSource.createModel('chapter', {title: String});
var Book = dataSource.createModel('book', {title: String, author: String});
var Chapter = dataSource.createModel('chapter', {title: String});
// by referencing model
Book.hasMany(Chapter);
Book.create({title: 'Into the Wild', author: 'Jon Krakauer'}, function(err, book) {
// using 'chapters' scope for build:
const c = book.chapters.build({title: 'Chapter 1'});
var c = book.chapters.build({title: 'Chapter 1'});
book.chapters.create({title: 'Chapter 2'}, function() {
c.save(function() {
Chapter.count({bookId: book.id}, function(err, count) {
@ -591,7 +591,7 @@ describe.onServer('Remote Methods', function() {
describe('Model.properties', function() {
it('Normalized properties passed in originally by loopback.createModel()', function() {
const props = {
var props = {
s: String,
n: {type: 'Number'},
o: {type: 'String', min: 10, max: 100},
@ -599,11 +599,11 @@ describe.onServer('Remote Methods', function() {
g: loopback.GeoPoint,
};
const MyModel = loopback.createModel('foo', props);
var MyModel = loopback.createModel('foo', props);
Object.keys(MyModel.definition.properties).forEach(function(key) {
const p = MyModel.definition.properties[key];
const o = MyModel.definition.properties[key];
var p = MyModel.definition.properties[key];
var o = MyModel.definition.properties[key];
assert(p);
assert(o);
assert(typeof p.type === 'function');
@ -613,7 +613,7 @@ describe.onServer('Remote Methods', function() {
// should match the given property
assert(
p.type.name === o.name ||
p.type.name === o,
p.type.name === o
);
}
});
@ -622,7 +622,7 @@ describe.onServer('Remote Methods', function() {
describe('Model.extend()', function() {
it('Create a new model by extending an existing model', function() {
const User = loopback.PersistedModel.extend('test-user', {
var User = loopback.PersistedModel.extend('test-user', {
email: String,
});
@ -634,7 +634,7 @@ describe.onServer('Remote Methods', function() {
return 'foo';
};
const MyUser = User.extend('my-user', {
var MyUser = User.extend('my-user', {
a: String,
b: String,
});
@ -642,7 +642,7 @@ describe.onServer('Remote Methods', function() {
assert.equal(MyUser.prototype.bar, User.prototype.bar);
assert.equal(MyUser.foo, User.foo);
const user = new MyUser({
var user = new MyUser({
email: 'foo@bar.com',
a: 'foo',
b: 'bar',
@ -656,21 +656,21 @@ describe.onServer('Remote Methods', function() {
describe('Model.extend() events', function() {
it('create isolated emitters for subclasses', function() {
const User1 = loopback.createModel('User1', {
var User1 = loopback.createModel('User1', {
'first': String,
'last': String,
});
const User2 = loopback.createModel('User2', {
var User2 = loopback.createModel('User2', {
'name': String,
});
let user1Triggered = false;
var user1Triggered = false;
User1.once('x', function(event) {
user1Triggered = true;
});
let user2Triggered = false;
var user2Triggered = false;
User2.once('x', function(event) {
user2Triggered = true;
});
@ -703,10 +703,10 @@ describe.onServer('Remote Methods', function() {
function shouldReturn(methodName, expectedAccessType) {
describe(methodName, function() {
it('should return ' + expectedAccessType, function() {
const remoteMethod = {name: methodName};
var remoteMethod = {name: methodName};
assert.equal(
User._getAccessTypeForMethod(remoteMethod),
expectedAccessType,
expectedAccessType
);
});
});
@ -715,8 +715,8 @@ describe.onServer('Remote Methods', function() {
describe('Model.getChangeModel()', function() {
it('Get the Change Model', function() {
const UserChange = User.getChangeModel();
const change = new UserChange();
var UserChange = User.getChangeModel();
var change = new UserChange();
assert(change instanceof app.registry.getModel('Change'));
});
});
@ -733,12 +733,12 @@ describe.onServer('Remote Methods', function() {
describe('Model.checkpoint(callback)', function() {
it('Create a checkpoint', function(done) {
const Checkpoint = User.getChangeModel().getCheckpointModel();
const tasks = [
var Checkpoint = User.getChangeModel().getCheckpointModel();
var tasks = [
getCurrentCheckpoint,
checkpoint,
];
let result, current;
var result, current;
async.series(tasks, function(err) {
if (err) return done(err);
@ -766,11 +766,11 @@ describe.onServer('Remote Methods', function() {
describe('Model._getACLModel()', function() {
it('should return the subclass of ACL', function() {
const Model = require('../').Model;
const originalValue = Model._ACL();
const acl = ACL.extend('acl');
var Model = require('../').Model;
var originalValue = Model._ACL();
var acl = ACL.extend('acl');
Model._ACL(null); // Reset the ACL class for the base model
const model = Model._ACL();
var model = Model._ACL();
Model._ACL(originalValue); // Reset the value back
assert.equal(model, acl);
});
@ -778,21 +778,21 @@ describe.onServer('Remote Methods', function() {
describe('PersistedModel remote methods', function() {
it('includes all aliases', function() {
const app = loopback();
const model = PersistedModel.extend('PersistedModelForAliases');
var app = loopback();
var model = PersistedModel.extend('PersistedModelForAliases');
app.dataSource('db', {connector: 'memory'});
app.model(model, {dataSource: 'db'});
// this code is used by loopback-sdk-angular codegen
const metadata = app.handler('rest')
var metadata = app.handler('rest')
.adapter
.getClasses()
.filter(function(c) { return c.name === model.modelName; })[0];
let methodNames = [];
var methodNames = [];
metadata.methods.forEach(function(method) {
methodNames.push(method.name);
let aliases = method.sharedMethod.aliases;
var aliases = method.sharedMethod.aliases;
if (method.name.indexOf('prototype.') === 0) {
aliases = aliases.map(function(alias) {
return 'prototype.' + alias;
@ -826,13 +826,13 @@ describe.onServer('Remote Methods', function() {
});
it('emits a `remoteMethodDisabled` event', function() {
const app = loopback();
const model = PersistedModel.extend('TestModelForDisablingRemoteMethod');
var app = loopback();
var model = PersistedModel.extend('TestModelForDisablingRemoteMethod');
app.dataSource('db', {connector: 'memory'});
app.model(model, {dataSource: 'db'});
const callbackSpy = require('sinon').spy();
const TestModel = app.models.TestModelForDisablingRemoteMethod;
var callbackSpy = require('sinon').spy();
var TestModel = app.models.TestModelForDisablingRemoteMethod;
TestModel.on('remoteMethodDisabled', callbackSpy);
TestModel.disableRemoteMethod('findOne', true);
@ -840,13 +840,13 @@ describe.onServer('Remote Methods', function() {
});
it('emits a `remoteMethodDisabled` event from disableRemoteMethodByName', function() {
const app = loopback();
const model = PersistedModel.extend('TestModelForDisablingRemoteMethod');
var app = loopback();
var model = PersistedModel.extend('TestModelForDisablingRemoteMethod');
app.dataSource('db', {connector: 'memory'});
app.model(model, {dataSource: 'db'});
const callbackSpy = require('sinon').spy();
const TestModel = app.models.TestModelForDisablingRemoteMethod;
var callbackSpy = require('sinon').spy();
var TestModel = app.models.TestModelForDisablingRemoteMethod;
TestModel.on('remoteMethodDisabled', callbackSpy);
TestModel.disableRemoteMethodByName('findOne');
@ -854,17 +854,17 @@ describe.onServer('Remote Methods', function() {
});
it('emits a `remoteMethodAdded` event', function() {
const app = loopback();
var app = loopback();
app.dataSource('db', {connector: 'memory'});
const User = app.registry.getModel('User');
var User = app.registry.getModel('User');
app.model(User, {dataSource: 'db'});
const Token = app.registry.getModel('AccessToken');
var Token = app.registry.getModel('AccessToken');
app.model(Token, {dataSource: 'db'});
const callbackSpy = require('sinon').spy();
const TestModel = app.models.User;
var callbackSpy = require('sinon').spy();
var TestModel = app.models.User;
TestModel.on('remoteMethodAdded', callbackSpy);
TestModel.nestRemoting('accessTokens');
@ -873,13 +873,13 @@ describe.onServer('Remote Methods', function() {
});
it('emits a `remoteMethodAdded` event from remoteMethod', function() {
const app = loopback();
const model = PersistedModel.extend('TestModelForAddingRemoteMethod');
var app = loopback();
var model = PersistedModel.extend('TestModelForAddingRemoteMethod');
app.dataSource('db', {connector: 'memory'});
app.model(model, {dataSource: 'db'});
const callbackSpy = require('sinon').spy();
const TestModel = app.models.TestModelForAddingRemoteMethod;
var callbackSpy = require('sinon').spy();
var TestModel = app.models.TestModelForAddingRemoteMethod;
TestModel.on('remoteMethodAdded', callbackSpy);
TestModel.remoteMethod('getTest', {
accepts: {arg: 'options', type: 'object', http: 'optionsFromRequest'},
@ -891,7 +891,7 @@ describe.onServer('Remote Methods', function() {
});
describe('Model.getApp(cb)', function() {
let app, TestModel;
var app, TestModel;
beforeEach(function setup() {
app = loopback();
TestModel = loopback.createModel('TestModelForGetApp'); // unique name
@ -924,15 +924,11 @@ describe.onServer('Remote Methods', function() {
});
describe('Model.createOptionsFromRemotingContext', function() {
let app, TestModel, accessToken, actualOptions;
var app, TestModel, accessToken, userId, actualOptions;
before(setupAppAndRequest);
before(createUserAndAccessToken);
beforeEach(function() {
TestModel.definition.settings = {};
});
it('sets empty options.accessToken for anonymous requests', function(done) {
request(app).get('/TestModels/saveOptions')
.expect(204, function(err) {
@ -942,36 +938,6 @@ describe.onServer('Remote Methods', function() {
});
});
it('sets options for juggler', function(done) {
request(app).get('/TestModels/saveOptions')
.expect(204, function(err) {
if (err) return done(err);
expect(actualOptions).to.include({
prohibitHiddenPropertiesInQuery: true,
maxDepthOfQuery: 12,
maxDepthOfData: 32,
});
done();
});
});
it('honors model settings to create options for juggler', function(done) {
TestModel.definition.settings = {
prohibitHiddenPropertiesInQuery: false,
maxDepthOfData: 64,
};
request(app).get('/TestModels/saveOptions')
.expect(204, function(err) {
if (err) return done(err);
expect(actualOptions).to.include({
prohibitHiddenPropertiesInQuery: false,
maxDepthOfQuery: 12,
maxDepthOfData: 64,
});
done();
});
});
it('sets options.accessToken for authorized requests', function(done) {
request(app).get('/TestModels/saveOptions')
.set('Authorization', accessToken.id)
@ -1055,13 +1021,14 @@ describe.onServer('Remote Methods', function() {
}
function createUserAndAccessToken() {
const CREDENTIALS = {email: 'context@example.com', password: 'pass'};
const User = app.registry.getModel('User');
var CREDENTIALS = {email: 'context@example.com', password: 'pass'};
var User = app.registry.getModel('User');
return User.create(CREDENTIALS)
.then(function(u) {
return User.login(CREDENTIALS);
}).then(function(token) {
accessToken = token;
userId = token.userId;
});
}
});

View File

@ -1,4 +1,4 @@
// Copyright IBM Corp. 2018,2019. All Rights Reserved.
// Copyright IBM Corp. 2016,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT

View File

@ -1,16 +1,16 @@
// Copyright IBM Corp. 2016,2019. All Rights Reserved.
// Copyright IBM Corp. 2016,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const expect = require('./helpers/expect');
const loopback = require('../');
const ctx = require('../lib/access-context');
const extend = require('util')._extend;
const AccessContext = ctx.AccessContext;
const Principal = ctx.Principal;
const Promise = require('bluebird');
var expect = require('./helpers/expect');
var loopback = require('../');
var ctx = require('../lib/access-context');
var extend = require('util')._extend;
var AccessContext = ctx.AccessContext;
var Principal = ctx.Principal;
var Promise = require('bluebird');
const waitForEvent = require('./helpers/wait-for-event');
const supertest = require('supertest');
const loggers = require('./helpers/error-loggers');
@ -19,8 +19,8 @@ const logServerErrorsOtherThan = loggers.logServerErrorsOtherThan;
describe('Multiple users with custom principalType', function() {
this.timeout(10000);
const commonCredentials = {email: 'foo@bar.com', password: 'bar'};
let app, OneUser, AnotherUser, AccessToken, Role,
var commonCredentials = {email: 'foo@bar.com', password: 'bar'};
var app, OneUser, AnotherUser, AccessToken, Role,
userFromOneModel, userFromAnotherModel, userRole, userOneBaseContext;
beforeEach(function setupAppAndModels() {
@ -30,7 +30,7 @@ describe('Multiple users with custom principalType', function() {
app.set('remoting', {rest: {handleErrors: false}});
app.dataSource('db', {connector: 'memory'});
const userModelOptions = {
var userModelOptions = {
base: 'User',
// forceId is set to false for the purpose of updating the same affected user within the
// `Email Update` test cases.
@ -101,7 +101,7 @@ describe('Multiple users with custom principalType', function() {
},
function onError(err) {
expect(err).to.have.property('code', 'LOGIN_FAILED');
},
}
);
});
});
@ -118,7 +118,7 @@ describe('Multiple users with custom principalType', function() {
describe('User.logout', function() {
it('logs out a user from user model 1 without logging out user from model 2',
function() {
let tokenOfOneUser;
var tokenOfOneUser;
return Promise.all([
OneUser.login(commonCredentials),
AnotherUser.login(commonCredentials),
@ -131,7 +131,7 @@ describe('Multiple users with custom principalType', function() {
return AccessToken.find({});
})
.then(function(allTokens) {
const data = allTokens.map(function(token) {
var data = allTokens.map(function(token) {
return {userId: token.userId, principalType: token.principalType};
});
expect(data).to.eql([
@ -144,7 +144,7 @@ describe('Multiple users with custom principalType', function() {
describe('Password Reset', function() {
describe('User.resetPassword(options)', function() {
const options = {
var options = {
email: 'foo@bar.com',
redirect: 'http://foobar.com/reset-password',
};
@ -172,7 +172,7 @@ describe('Multiple users with custom principalType', function() {
});
describe('AccessToken (session) invalidation when changing email', function() {
let anotherUserFromOneModel;
var anotherUserFromOneModel;
it('impact only the related user', function() {
return OneUser.create({email: 'original@example.com', password: 'bar'})
@ -192,7 +192,7 @@ describe('Multiple users with custom principalType', function() {
return AccessToken.find({'order': 'principalType ASC'});
})
.then(function(allTokens) {
const data = allTokens.map(function(token) {
var data = allTokens.map(function(token) {
return {userId: token.userId, principalType: token.principalType};
});
expect(data).to.eql([
@ -205,7 +205,7 @@ describe('Multiple users with custom principalType', function() {
});
describe('AccessContext', function() {
let ThirdUser, userFromThirdModel, accessContext;
var ThirdUser, userFromThirdModel, accessContext;
beforeEach(function() {
accessContext = new AccessContext({registry: OneUser.registry});
@ -221,7 +221,7 @@ describe('Multiple users with custom principalType', function() {
{type: Principal.SCOPE},
{type: OneUser.modelName, id: userFromOneModel.id},
]);
const user = accessContext.getUser();
var user = accessContext.getUser();
expect(user).to.eql({
id: userFromOneModel.id,
principalType: OneUser.modelName,
@ -237,7 +237,7 @@ describe('Multiple users with custom principalType', function() {
{type: 'invalidModelName'},
{type: OneUser.modelName, id: userFromOneModel.id},
]);
const user = accessContext.getUser();
var user = accessContext.getUser();
expect(user).to.eql({
id: userFromOneModel.id,
principalType: OneUser.modelName,
@ -251,7 +251,7 @@ describe('Multiple users with custom principalType', function() {
return ThirdUser.create(commonCredentials)
.then(function(userFromThirdModel) {
accessContext.addPrincipal(ThirdUser.modelName, userFromThirdModel.id);
const user = accessContext.getUser();
var user = accessContext.getUser();
expect(user).to.eql({
id: userFromThirdModel.id,
principalType: ThirdUser.modelName,
@ -272,7 +272,7 @@ describe('Multiple users with custom principalType', function() {
describe('Role model', function() {
this.timeout(10000);
let RoleMapping, ACL, user;
var RoleMapping, ACL, user;
beforeEach(function() {
ACL = app.registry.getModel('ACL');
@ -285,7 +285,7 @@ describe('Multiple users with custom principalType', function() {
describe('role.users()', function() {
it('returns users when using custom user principalType', function() {
return userRole.principals.create(
{principalType: OneUser.modelName, principalId: userFromOneModel.id},
{principalType: OneUser.modelName, principalId: userFromOneModel.id}
)
.then(function() {
return userRole.users({where: {principalType: OneUser.modelName}});
@ -298,7 +298,7 @@ describe('Multiple users with custom principalType', function() {
it('returns empty array when using invalid principalType', function() {
return userRole.principals.create(
{principalType: 'invalidModelName', principalId: userFromOneModel.id},
{principalType: 'invalidModelName', principalId: userFromOneModel.id}
)
.then(function() {
return userRole.users({where: {principalType: 'invalidModelName'}});
@ -312,7 +312,7 @@ describe('Multiple users with custom principalType', function() {
describe('principal.user()', function() {
it('returns the correct user instance', function() {
return userRole.principals.create(
{principalType: OneUser.modelName, principalId: userFromOneModel.id},
{principalType: OneUser.modelName, principalId: userFromOneModel.id}
).then(function(principal) {
return principal.user();
}).then(function(user) {
@ -322,7 +322,7 @@ describe('Multiple users with custom principalType', function() {
it('returns null when created with invalid principalType', function() {
return userRole.principals.create(
{principalType: 'invalidModelName', principalId: userFromOneModel.id},
{principalType: 'invalidModelName', principalId: userFromOneModel.id}
).then(function(principal) {
return principal.user();
}).then(function(user) {
@ -346,7 +346,7 @@ describe('Multiple users with custom principalType', function() {
it('supports getRoles()', function() {
return Role.getRoles(
userOneBaseContext,
userOneBaseContext
).then(function(roles) {
expect(roles).to.eql([
Role.AUTHENTICATED,
@ -374,7 +374,7 @@ describe('Multiple users with custom principalType', function() {
describe('$owner', function() {
it('supports legacy behavior with relations', function() {
const Album = app.registry.createModel('Album', {
var Album = app.registry.createModel('Album', {
name: String,
userId: Number,
}, {
@ -390,7 +390,7 @@ describe('Multiple users with custom principalType', function() {
return Album.create({name: 'album', userId: userFromOneModel.id})
.then(function(album) {
const validContext = {
var validContext = {
principalType: OneUser.modelName,
principalId: userFromOneModel.id,
model: Album,
@ -406,7 +406,7 @@ describe('Multiple users with custom principalType', function() {
// With multiple users config, we cannot resolve a user based just on
// his id, as many users from different models could have the same id.
it('legacy behavior resolves false without belongsTo relation', function() {
const Album = app.registry.createModel('Album', {
var Album = app.registry.createModel('Album', {
name: String,
userId: Number,
owner: Number,
@ -419,7 +419,7 @@ describe('Multiple users with custom principalType', function() {
owner: userFromOneModel.id,
})
.then(function(album) {
const authContext = {
var authContext = {
principalType: OneUser.modelName,
principalId: userFromOneModel.id,
model: Album,
@ -433,7 +433,7 @@ describe('Multiple users with custom principalType', function() {
});
it('legacy behavior resolves false if owner has incorrect principalType', function() {
const Album = app.registry.createModel('Album', {
var Album = app.registry.createModel('Album', {
name: String,
userId: Number,
}, {
@ -449,12 +449,12 @@ describe('Multiple users with custom principalType', function() {
return Album.create({name: 'album', userId: userFromOneModel.id})
.then(function(album) {
const invalidPrincipalTypes = [
var invalidPrincipalTypes = [
'invalidContextName',
'USER',
AnotherUser.modelName,
];
const invalidContexts = invalidPrincipalTypes.map(principalType => {
var invalidContexts = invalidPrincipalTypes.map(principalType => {
return {
principalType,
principalId: userFromOneModel.id,
@ -485,12 +485,12 @@ describe('Multiple users with custom principalType', function() {
function() {
// passing {ownerRelations: true} will enable the new $owner role resolver
// with any belongsTo relation allowing to resolve truthy
const Message = createModelWithOptions(
var Message = createModelWithOptions(
'ModelWithAllRelations',
{ownerRelations: true},
{ownerRelations: true}
);
const messages = [
var messages = [
{content: 'firstMessage', customerId: userFromOneModel.id},
{
content: 'secondMessage',
@ -552,7 +552,7 @@ describe('Multiple users with custom principalType', function() {
// helpers
function isOwnerForMessage(user, msg) {
const accessContext = {
var accessContext = {
principalType: user.constructor.modelName,
principalId: user.id,
model: msg.constructor,
@ -569,7 +569,7 @@ describe('Multiple users with custom principalType', function() {
}
function createModelWithOptions(name, options) {
const baseOptions = {
var baseOptions = {
relations: {
sender: {
type: 'belongsTo',
@ -584,10 +584,10 @@ describe('Multiple users with custom principalType', function() {
},
};
options = extend(baseOptions, options);
const Model = app.registry.createModel(
var Model = app.registry.createModel(
name,
{content: String, senderType: String},
options,
options
);
app.model(Model, {dataSource: 'db'});
return Model;
@ -616,7 +616,7 @@ describe('Multiple users with custom principalType', function() {
function onError(err) {
expect(err).to.have.property('statusCode', 400);
expect(err).to.have.property('code', 'INVALID_PRINCIPAL_TYPE');
},
}
);
});
@ -768,7 +768,7 @@ describe('Multiple users with custom principalType', function() {
// helpers
function createUserModel(app, name, options) {
const model = app.registry.createModel(Object.assign({name: name}, options));
var model = app.registry.createModel(Object.assign({name: name}, options));
app.model(model, {dataSource: 'db'});
model.setMaxListeners(0); // allow many User.afterRemote's to be called
return model;
@ -778,9 +778,9 @@ describe('Multiple users with custom principalType', function() {
return new Promise(function(resolve, reject) {
emitter.once(name, resolve);
});
}
};
function getIds(array) {
return array.map(function(it) { return it.id; });
}
};
});

View File

@ -1,19 +1,19 @@
// Copyright IBM Corp. 2015,2019. All Rights Reserved.
// Copyright IBM Corp. 2015,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const assert = require('assert');
const expect = require('./helpers/expect');
const loopback = require('../');
var assert = require('assert');
var expect = require('./helpers/expect');
var loopback = require('../');
describe('Registry', function() {
describe('createModel', function() {
it('should throw error upon extending non-exist base model', function() {
const app = loopback();
const props = {};
const opts = {base: 'nonexistent'};
var app = loopback();
var props = {};
var opts = {base: 'nonexistent'};
expect(function() { app.registry.createModel('aModel', props, opts); })
.to.throw(/model\s`aModel`(.*)unknown\smodel\s`nonexistent`/);
});
@ -21,26 +21,26 @@ describe('Registry', function() {
describe('one per app', function() {
it('should allow two apps to reuse the same model name', function(done) {
const appFoo = loopback();
const appBar = loopback();
const modelName = 'MyModel';
const subModelName = 'Sub' + modelName;
const settings = {base: 'PersistedModel'};
var appFoo = loopback();
var appBar = loopback();
var modelName = 'MyModel';
var subModelName = 'Sub' + modelName;
var settings = {base: 'PersistedModel'};
appFoo.set('perAppRegistries', true);
appBar.set('perAppRegistries', true);
const dsFoo = appFoo.dataSource('dsFoo', {connector: 'memory'});
const dsBar = appFoo.dataSource('dsBar', {connector: 'memory'});
var dsFoo = appFoo.dataSource('dsFoo', {connector: 'memory'});
var dsBar = appFoo.dataSource('dsBar', {connector: 'memory'});
const FooModel = appFoo.registry.createModel(modelName, {}, settings);
var FooModel = appFoo.registry.createModel(modelName, {}, settings);
appFoo.model(FooModel, {dataSource: dsFoo});
const FooSubModel = appFoo.registry.createModel(subModelName, {}, settings);
var FooSubModel = appFoo.registry.createModel(subModelName, {}, settings);
appFoo.model(FooSubModel, {dataSource: dsFoo});
const BarModel = appBar.registry.createModel(modelName, {}, settings);
var BarModel = appBar.registry.createModel(modelName, {}, settings);
appBar.model(BarModel, {dataSource: dsBar});
const BarSubModel = appBar.registry.createModel(subModelName, {}, settings);
var BarSubModel = appBar.registry.createModel(subModelName, {}, settings);
appBar.model(BarSubModel, {dataSource: dsBar});
FooModel.hasMany(FooSubModel);

File diff suppressed because it is too large Load Diff

View File

@ -1,21 +1,21 @@
// Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Copyright IBM Corp. 2014,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const assert = require('assert');
const loopback = require('../');
const defineModelTestsWithDataSource = require('./util/model-tests');
var assert = require('assert');
var loopback = require('../');
var defineModelTestsWithDataSource = require('./util/model-tests');
describe('RemoteConnector', function() {
this.timeout(10000);
let remoteApp, remote;
var remoteApp, remote;
defineModelTestsWithDataSource({
beforeEach: function(done) {
const test = this;
var test = this;
remoteApp = loopback();
remoteApp.set('remoting', {
errorHandler: {debug: true, log: false},
@ -40,7 +40,7 @@ describe('RemoteConnector', function() {
enableRemoteReplication: true,
onDefine: function(Model) {
const ServerModel = Model.extend('Server' + Model.modelName, {}, {
var ServerModel = Model.extend('Server' + Model.modelName, {}, {
plural: Model.pluralModelName,
// This is the model running on the server & attached to a real
// datasource, that's the place where to keep track of changes
@ -54,13 +54,13 @@ describe('RemoteConnector', function() {
});
beforeEach(function(done) {
const test = this;
var test = this;
remoteApp = this.remoteApp = loopback();
remoteApp.set('remoting', {
types: {warnWhenOverridingType: false},
});
remoteApp.use(loopback.rest());
const ServerModel = this.ServerModel = loopback.PersistedModel.extend('TestModel');
var ServerModel = this.ServerModel = loopback.PersistedModel.extend('TestModel');
remoteApp.model(ServerModel);
@ -76,11 +76,11 @@ describe('RemoteConnector', function() {
});
it('should support the save method', function(done) {
let calledServerCreate = false;
const RemoteModel = loopback.PersistedModel.extend('TestModel');
var calledServerCreate = false;
var RemoteModel = loopback.PersistedModel.extend('TestModel');
RemoteModel.attachTo(this.remote);
const ServerModel = this.ServerModel;
var ServerModel = this.ServerModel;
ServerModel.create = function(data, options, cb) {
calledServerCreate = true;
@ -90,7 +90,7 @@ describe('RemoteConnector', function() {
ServerModel.setupRemoting();
const m = new RemoteModel({foo: 'bar'});
var m = new RemoteModel({foo: 'bar'});
m.save(function(err, inst) {
if (err) return done(err);

View File

@ -1,20 +1,20 @@
// Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Copyright IBM Corp. 2014,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const assert = require('assert');
const loopback = require('../');
const request = require('supertest');
var assert = require('assert');
var loopback = require('../');
var request = require('supertest');
describe('remoting coercion', function() {
it('should coerce arguments based on the type', function(done) {
let called = false;
const app = loopback();
var called = false;
var app = loopback();
app.use(loopback.rest());
const TestModel = app.registry.createModel('TestModel',
var TestModel = app.registry.createModel('TestModel',
{},
{base: 'Model'});
app.model(TestModel, {public: true});

View File

@ -1,16 +1,16 @@
// Copyright IBM Corp. 2014,2019. All Rights Reserved.
// Copyright IBM Corp. 2014,2018. All Rights Reserved.
// Node module: loopback
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const loopback = require('../');
const lt = require('./helpers/loopback-testing-helper');
const path = require('path');
const SIMPLE_APP = path.join(__dirname, 'fixtures', 'simple-integration-app');
const app = require(path.join(SIMPLE_APP, 'server/server.js'));
const assert = require('assert');
const expect = require('./helpers/expect');
var loopback = require('../');
var lt = require('./helpers/loopback-testing-helper');
var path = require('path');
var SIMPLE_APP = path.join(__dirname, 'fixtures', 'simple-integration-app');
var app = require(path.join(SIMPLE_APP, 'server/server.js'));
var assert = require('assert');
var expect = require('./helpers/expect');
describe('remoting - integration', function() {
lt.beforeEach.withApp(app);
@ -22,21 +22,21 @@ describe('remoting - integration', function() {
describe('app.remotes.options', function() {
it('should load remoting options', function() {
const remotes = app.remotes();
var remotes = app.remotes();
assert.deepEqual(remotes.options, {'json': {'limit': '1kb', 'strict': false},
'urlencoded': {'limit': '8kb', 'extended': true},
'errorHandler': {'debug': true, log: false}});
});
it('rest handler', function() {
const handler = app.handler('rest');
var handler = app.handler('rest');
assert(handler);
});
it('should accept request that has entity below 1kb', function(done) {
// Build an object that is smaller than 1kb
let name = '';
for (let i = 0; i < 256; i++) {
var name = '';
for (var i = 0; i < 256; i++) {
name += '11';
}
this.http = this.post('/api/stores');
@ -55,8 +55,8 @@ describe('remoting - integration', function() {
it('should reject request that has entity beyond 1kb', function(done) {
// Build an object that is larger than 1kb
let name = '';
for (let i = 0; i < 2048; i++) {
var name = '';
for (var i = 0; i < 2048; i++) {
name += '11111111111';
}
this.http = this.post('/api/stores');
@ -79,10 +79,10 @@ describe('remoting - integration', function() {
it('has expected remote methods with default model.settings.replaceOnPUT' +
'set to true (3.x)',
function() {
const storeClass = findClass('store');
const methods = getFormattedMethodsExcludingRelations(storeClass.methods);
var storeClass = findClass('store');
var methods = getFormattedMethodsExcludingRelations(storeClass.methods);
const expectedMethods = [
var expectedMethods = [
'create(data:object:store):store POST /stores',
'patchOrCreate(data:object:store):store PATCH /stores',
'replaceOrCreate(data:object:store):store PUT /stores',
@ -106,10 +106,10 @@ describe('remoting - integration', function() {
});
it('has expected remote methods for scopes', function() {
const storeClass = findClass('store');
const methods = getFormattedScopeMethods(storeClass.methods);
var storeClass = findClass('store');
var methods = getFormattedScopeMethods(storeClass.methods);
const expectedMethods = [
var expectedMethods = [
'__get__superStores(filter:object):store GET /stores/superStores',
'__create__superStores(data:object:store):store POST /stores/superStores',
'__delete__superStores() DELETE /stores/superStores',
@ -121,10 +121,10 @@ describe('remoting - integration', function() {
it('should have correct signatures for belongsTo methods',
function() {
const widgetClass = findClass('widget');
const methods = getFormattedPrototypeMethods(widgetClass.methods);
var widgetClass = findClass('widget');
var methods = getFormattedPrototypeMethods(widgetClass.methods);
const expectedMethods = [
var expectedMethods = [
'prototype.__get__store(refresh:boolean):store ' +
'GET /widgets/:id/store',
];
@ -133,10 +133,10 @@ describe('remoting - integration', function() {
it('should have correct signatures for hasMany methods',
function() {
const storeClass = findClass('store');
const methods = getFormattedPrototypeMethods(storeClass.methods);
var storeClass = findClass('store');
var methods = getFormattedPrototypeMethods(storeClass.methods);
const expectedMethods = [
var expectedMethods = [
'prototype.__findById__widgets(fk:any):widget ' +
'GET /stores/:id/widgets/:fk',
'prototype.__destroyById__widgets(fk:any) ' +
@ -157,10 +157,10 @@ describe('remoting - integration', function() {
it('should have correct signatures for hasMany-through methods',
function() { // jscs:disable validateIndentation
const physicianClass = findClass('physician');
const methods = getFormattedPrototypeMethods(physicianClass.methods);
var physicianClass = findClass('physician');
var methods = getFormattedPrototypeMethods(physicianClass.methods);
const expectedMethods = [
var expectedMethods = [
'prototype.__findById__patients(fk:any):patient ' +
'GET /physicians/:id/patients/:fk',
'prototype.__destroyById__patients(fk:any) ' +
@ -187,9 +187,9 @@ describe('remoting - integration', function() {
});
it('has upsertWithWhere remote method', function() {
const storeClass = findClass('store');
const methods = getFormattedMethodsExcludingRelations(storeClass.methods);
const expectedMethods = [
var storeClass = findClass('store');
var methods = getFormattedMethodsExcludingRelations(storeClass.methods);
var expectedMethods = [
'upsertWithWhere(where:object,data:object:store):store POST /stores/upsertWithWhere',
];
expect(methods).to.include.members(expectedMethods);
@ -198,21 +198,21 @@ describe('remoting - integration', function() {
describe('createOnlyInstance', function() {
it('sets createOnlyInstance to true if id is generated and forceId is not set to false',
function() {
const storeClass = findClass('store');
const createMethod = getCreateMethod(storeClass.methods);
var storeClass = findClass('store');
var createMethod = getCreateMethod(storeClass.methods);
assert(createMethod.accepts[0].createOnlyInstance === true);
});
it('sets createOnlyInstance to false if forceId is set to false in the model', function() {
const customerClass = findClass('customerforceidfalse');
const createMethod = getCreateMethod(customerClass.methods);
var customerClass = findClass('customerforceidfalse');
var createMethod = getCreateMethod(customerClass.methods);
assert(createMethod.accepts[0].createOnlyInstance === false);
});
it('sets createOnlyInstance based on target model for scoped or related methods',
function() {
const userClass = findClass('user');
const createMethod = userClass.methods.find(function(m) {
var userClass = findClass('user');
var createMethod = userClass.methods.find(function(m) {
return (m.name === 'prototype.__create__accessTokens');
});
assert(createMethod.accepts[0].createOnlyInstance === false);
@ -229,10 +229,10 @@ describe('With model.settings.replaceOnPUT false', function() {
it('should have expected remote methods',
function() {
const storeClass = findClass('storeWithReplaceOnPUTfalse');
const methods = getFormattedMethodsExcludingRelations(storeClass.methods);
var storeClass = findClass('storeWithReplaceOnPUTfalse');
var methods = getFormattedMethodsExcludingRelations(storeClass.methods);
const expectedMethods = [
var expectedMethods = [
'create(data:object:storeWithReplaceOnPUTfalse):storeWithReplaceOnPUTfalse POST /stores-updating',
'patchOrCreate(data:object:storeWithReplaceOnPUTfalse):storeWithReplaceOnPUTfalse PUT /stores-updating',
'patchOrCreate(data:object:storeWithReplaceOnPUTfalse):storeWithReplaceOnPUTfalse PATCH /stores-updating',
@ -266,10 +266,10 @@ describe('With model.settings.replaceOnPUT true', function() {
it('should have expected remote methods',
function() {
const storeClass = findClass('storeWithReplaceOnPUTtrue');
const methods = getFormattedMethodsExcludingRelations(storeClass.methods);
var storeClass = findClass('storeWithReplaceOnPUTtrue');
var methods = getFormattedMethodsExcludingRelations(storeClass.methods);
const expectedMethods = [
var expectedMethods = [
'patchOrCreate(data:object:storeWithReplaceOnPUTtrue):storeWithReplaceOnPUTtrue PATCH /stores-replacing',
'replaceOrCreate(data:object:storeWithReplaceOnPUTtrue):storeWithReplaceOnPUTtrue POST /stores-replacing/replaceOrCreate',
'replaceOrCreate(data:object:storeWithReplaceOnPUTtrue):storeWithReplaceOnPUTtrue PUT /stores-replacing',
@ -283,11 +283,11 @@ describe('With model.settings.replaceOnPUT true', function() {
});
function formatReturns(m) {
const returns = m.returns;
var returns = m.returns;
if (!returns || returns.length === 0) {
return '';
}
let type = returns[0].type;
var type = returns[0].type;
// handle anonymous type definitions, e.g
// { arg: 'info', type: { count: 'number' } }
@ -298,9 +298,9 @@ function formatReturns(m) {
}
function formatMethod(m) {
const arr = [];
const endpoints = m.getEndpoints();
for (let i = 0; i < endpoints.length; i++) {
var arr = [];
var endpoints = m.getEndpoints();
for (var i = 0; i < endpoints.length; i++) {
arr.push([
m.name,
'(',

Some files were not shown because too many files have changed in this diff Show More