├── .eslintrc ├── .gitignore ├── README.md ├── lib ├── index.js └── rules │ ├── detect-angular-element-methods.js │ ├── detect-angular-open-redirect.js │ ├── detect-angular-orderBy-expressions.js │ ├── detect-angular-resource-loading.js │ ├── detect-angular-sce-disabled.js │ ├── detect-angular-scope-expressions.js │ ├── detect-angular-service-expressions.js │ ├── detect-angular-trustAs-methods.js │ ├── detect-angular-trustAsCss-method.js │ ├── detect-angular-trustAsHtml-method.js │ ├── detect-angular-trustAsJs-method.js │ ├── detect-angular-trustAsResourceUrl-method.js │ ├── detect-angular-trustAsUrl-method.js │ └── detect-third-party-angular-translate.js ├── package-lock.json ├── package.json └── tests └── rules ├── detect-angular-element-methods.js ├── detect-angular-open-redirect.js ├── detect-angular-orderBy-expressions.js ├── detect-angular-resource-loading.js ├── detect-angular-sce-disabled.js ├── detect-angular-scope-expressions.js ├── detect-angular-service-expressions.js ├── detect-angular-trustAs-methods.js ├── detect-angular-trustAsCss-method.js ├── detect-angular-trustAsHtml-method.js ├── detect-angular-trustAsJs-method.js ├── detect-angular-trustAsResouceUrl-method.js └── detect-third-party-angular-translate.js /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "babel-eslint", 3 | "plugins": [ 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | lib/experimental 2 | node_modules -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AngularJS Security Rules For ESLint 2 | 3 | These rules are to supplement the security issues documented in my talks at [OWASP London](https://www.slideshare.net/LewisArdern/owasp-london-so-you-thought-you-were-safe-using-angularjs-think-again) and [FluentConf](https://www.slideshare.net/LewisArdern/so-you-thought-you-were-safe-using-angularjs-think-again) around AngularJS Security. 4 | 5 | They are currently used as points of interest that would need to be investigate further, but in the upcoming releases they will be a lot more useful when developers write code. 6 | 7 | # Usage 8 | 9 | These rules can be used by downloading the [Config](https://github.com/LewisArdern/eslint-config-angular-security) which includes the installation settings. 10 | 11 | ## Rules 12 | 13 | The current ruleset supports only Angular 1.x issues, and can be noisy, but they are a work in progress. 14 | 15 | Current rules are: 16 | * detect-angular-element-methods 17 | * detect-angular-open-redirect 18 | * detect-angular-orderBy-expressions 19 | * detect-angular-resource-loading 20 | * detect-angular-sce-disabled 21 | * detect-angular-scope-expressions 22 | * detect-angular-service-expressions 23 | * detect-angular-trustAs-methods 24 | * detect-angular-trustAsCss-method 25 | * detect-angular-trustAsHtml-method 26 | * detect-angular-sce-disabled 27 | * detect-angular-trustAsJs-method 28 | * detect-angular-trustAsResourceUrl-method 29 | * detect-angular-trustAsUrl-method 30 | * detect-third-party-angular-translate 31 | 32 | TODO: 33 | * Each rule needs better detection, and possibly taint analysis 34 | * Add more rules related to Angular 1.0 - 5 in mind. 35 | * Add Angular 2/4 security issues such as [bypassSecurityTrustHtml](https://angular.io/api/platform-browser/DomSanitizer#bypassSecurityTrustHtml) 36 | 37 | If you feel anything is missing or would like to see additional rules added, feel free to write an [issue](https://github.com/LewisArdern/eslint-plugin-angularjs-security-rules/issues) -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview AngularJS Rules 3 | * @author Lewis Ardern 4 | */ 5 | "use strict"; 6 | 7 | //------------------------------------------------------------------------------ 8 | // Requirements 9 | //------------------------------------------------------------------------------ 10 | 11 | var requireIndex = require("requireindex"); 12 | 13 | //------------------------------------------------------------------------------ 14 | // Plugin Definition 15 | //------------------------------------------------------------------------------ 16 | 17 | 18 | // import all rules in lib/rules 19 | module.exports.rules = requireIndex(__dirname + "/rules"); 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /lib/rules/detect-angular-element-methods.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview Rule to detect use of angular.element 3 | * @author Lewis Ardern 4 | */ 5 | 6 | "use strict"; 7 | 8 | module.exports = { 9 | create: function (context) { 10 | return { 11 | MemberExpression: function (node) { 12 | // TODO: Create some kind of taint analysis to identify use of after,append,html,prepend,replaceWith,wrap 13 | // Not as simple as angular.element().after e.g let element = angular.element(), and then use element.after() etc. 14 | if (node.object.name === 'angular' && node.property.name === 'element') { 15 | context.report(node, "Use of angular.element can lead to XSS if after,append,html,prepend,replaceWith,wrap are used with user-input"); 16 | }; 17 | } 18 | }; 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /lib/rules/detect-angular-open-redirect.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview Rule to detect use of $window.location.href 3 | * @author Lewis Ardern 4 | */ 5 | 6 | "use strict"; 7 | 8 | module.exports = { 9 | create: function (context) { 10 | return { 11 | MemberExpression: function (node) { 12 | if (node.object.name === '$window' && node.property.name === 'location' && node.parent.property && node.parent.property.name === 'href') { 13 | context.report(node, "Use of $window.location.href can lead to open-redirect"); 14 | }; 15 | } 16 | }; 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /lib/rules/detect-angular-orderBy-expressions.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview Rule to detect use of the orderBy filter 3 | * @author Lewis Ardern 4 | */ 5 | 6 | "use strict"; 7 | 8 | module.exports = { 9 | 10 | create: function (context) { 11 | return { 12 | CallExpression: function (node) { 13 | 14 | //TODO: Look at identifying HTML {{ expressions for the | orderBy }} 15 | //TODO: Look at picking out a function called orderByFilter 16 | if (node.callee.name == "$filter") { 17 | var args = node.arguments[0]; 18 | if (typeof args !== undefined) { 19 | if (args.raw === 'orderBy' || args.value === 'orderBy') { 20 | context.report(node, `The method ${node.callee.name}('orderBy') can be dangerous`); 21 | } 22 | } 23 | } 24 | } 25 | } 26 | }, 27 | }; 28 | -------------------------------------------------------------------------------- /lib/rules/detect-angular-resource-loading.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview Rule to detect use of $sceDelegateProvider whitelists resources 3 | * @author Lewis Ardern 4 | */ 5 | 6 | "use strict"; 7 | 8 | module.exports = { 9 | create: function (context) { 10 | return { 11 | MemberExpression: function (node) { 12 | if (node.object.name == '$sceDelegateProvider' && node.property.name == 'resourceUrlWhitelist') { 13 | context.report(node, "$sceDelegateProvider whitelisting can be introduce security issues"); 14 | }; 15 | } 16 | }; 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /lib/rules/detect-angular-sce-disabled.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview Rule to detect use of $sceProvider set to false 3 | * @author Lewis Ardern 4 | */ 5 | 6 | "use strict"; 7 | 8 | module.exports = { 9 | create: function (context) { 10 | return { 11 | // TODO: Identify best way to identify variable declariation for $sceProvider to make this rule smarter. 12 | // it will miss var x = $sceDelegateProvider; x.enabled(false); 13 | // Could just look for the use of $sceProvider in the meantime, but for now rule serves a purpose. 14 | MemberExpression: function (node) { 15 | if (node.object.name === '$sceProvider' && node.property.name === 'enabled') { 16 | var args = node.parent.arguments[0]; 17 | if (typeof args !== undefined) { 18 | if (args.value === false || args.raw === false) { 19 | context.report(node, "$sceProvider is set to false"); 20 | } 21 | } 22 | }; 23 | } 24 | }; 25 | } 26 | }; 27 | -------------------------------------------------------------------------------- /lib/rules/detect-angular-scope-expressions.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview Rule to detect use of dangerous AngularJS expressions 3 | * @author Lewis Ardern 4 | */ 5 | 6 | "use strict"; 7 | 8 | module.exports = { 9 | 10 | create: function (context) { 11 | return { 12 | MemberExpression: function (node) { 13 | // These methods are called via $scope or $rootScope most of the time, so they will be a MemberExpression. 14 | // TODO: Only time it might not be picked up is in custom directives, but need to test. 15 | const expressions = ['$eval', '$evalAsync', '$apply', '$applyAsync', '$watch', '$watchGroup', '$watchCollection']; 16 | 17 | expressions.map(expression => { 18 | if (expression.indexOf(node.property.name) === 0 && expression.length === node.property.name.length) { 19 | context.report(node, `The method ${node.property.name} can be dangerous`); 20 | } 21 | }) 22 | } 23 | }; 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /lib/rules/detect-angular-service-expressions.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview Rule to detect use of dangerous AngularJS expressions 3 | * @author Lewis Ardern 4 | */ 5 | 6 | "use strict"; 7 | 8 | module.exports = { 9 | 10 | create: function (context) { 11 | return { 12 | CallExpression: function (node) { 13 | const expressions = ['$compile', '$parse', '$interpolate']; 14 | 15 | expressions.map(expression => { 16 | if (expression.indexOf(node.callee.name) === 0 && expression.length === node.callee.name.length) { 17 | context.report(node, `The method ${node.callee.name} can be dangerous`); 18 | } 19 | }) 20 | } 21 | }; 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /lib/rules/detect-angular-trustAs-methods.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview Rule to detect use of explcility trusted content 3 | * @author Lewis Ardern 4 | */ 5 | 6 | "use strict"; 7 | 8 | module.exports = { 9 | 10 | create: function (context) { 11 | return { 12 | "CallExpression[callee.property.name=trustAs][callee.object.name=$sce]": function (node) { 13 | if (node.arguments[1] && node.arguments[1].type === 'Literal') { 14 | return; 15 | } else { 16 | context.report(node, `The use of $sce.trustAs can be dangerous`); 17 | } 18 | }, 19 | "CallExpression[callee.property.name=trustAs] MemberExpression[property.name=$sce]": function (node) { 20 | var args = node.parent.parent.arguments; 21 | if (args && args[1].type === 'Literal') { 22 | return; 23 | } else { 24 | context.report(node, `The use of $sce.trustAs can be dangerous`); 25 | } 26 | } 27 | }; 28 | } 29 | }; -------------------------------------------------------------------------------- /lib/rules/detect-angular-trustAsCss-method.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview Rule to detect use of explcility trusted content 3 | * @author Lewis Ardern 4 | */ 5 | 6 | "use strict"; 7 | 8 | module.exports = { 9 | 10 | create: function (context) { 11 | return { 12 | "CallExpression[callee.property.name=trustAsCss][callee.object.name=$sce]": function (node) { 13 | if (node.arguments[0] && node.arguments[0].type === 'Literal') { 14 | return; 15 | } else { 16 | context.report(node, `The use of $sce.trustAsCss can be dangerous`); 17 | } 18 | }, 19 | "CallExpression[callee.property.name=trustAsCss] MemberExpression[property.name=$sce]": function (node) { 20 | var args = node.parent.parent.arguments; 21 | if (args && args[0].type === 'Literal') { 22 | return; 23 | } else { 24 | context.report(node, `The use of $sce.trustAsCss can be dangerous`); 25 | } 26 | } 27 | }; 28 | } 29 | }; -------------------------------------------------------------------------------- /lib/rules/detect-angular-trustAsHtml-method.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview Rule to detect use of explcility trusted content 3 | * @author Lewis Ardern 4 | */ 5 | 6 | "use strict"; 7 | 8 | module.exports = { 9 | 10 | create: function (context) { 11 | return { 12 | "CallExpression[callee.property.name=trustAsHtml][callee.object.name=$sce]": function (node) { 13 | if (node.arguments[0] && node.arguments[0].type === 'Literal') { 14 | return; 15 | } else { 16 | context.report(node, `The use of $sce.trustAsHtml can be dangerous`); 17 | } 18 | }, 19 | "CallExpression[callee.property.name=trustAsHtml] MemberExpression[property.name=$sce]": function (node) { 20 | var args = node.parent.parent.arguments; 21 | if (args && args[0].type === 'Literal') { 22 | return; 23 | } else { 24 | context.report(node, `The use of $sce.trustAsHtml can be dangerous`); 25 | } 26 | } 27 | }; 28 | } 29 | }; -------------------------------------------------------------------------------- /lib/rules/detect-angular-trustAsJs-method.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview Rule to detect use of explcility trusted content 3 | * @author Lewis Ardern 4 | */ 5 | 6 | "use strict"; 7 | 8 | module.exports = { 9 | 10 | create: function (context) { 11 | return { 12 | "CallExpression[callee.property.name=trustAsJs][callee.object.name=$sce]": function (node) { 13 | if (node.arguments[0] && node.arguments[0].type === 'Literal') { 14 | return; 15 | } else { 16 | context.report(node, `The use of $sce.trustAsJs can be dangerous`); 17 | } 18 | }, 19 | "CallExpression[callee.property.name=trustAsJs] MemberExpression[property.name=$sce]": function (node) { 20 | var args = node.parent.parent.arguments; 21 | if (args && args[0].type === 'Literal') { 22 | return; 23 | } else { 24 | context.report(node, `The use of $sce.trustAsJs can be dangerous`); 25 | } 26 | } 27 | }; 28 | } 29 | }; -------------------------------------------------------------------------------- /lib/rules/detect-angular-trustAsResourceUrl-method.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview Rule to detect use of explcility trusted content 3 | * @author Lewis Ardern 4 | */ 5 | 6 | "use strict"; 7 | 8 | module.exports = { 9 | 10 | create: function (context) { 11 | return { 12 | "CallExpression[callee.property.name=trustAsResourceUrl][callee.object.name=$sce]": function (node) { 13 | if (node.arguments[0] && node.arguments[0].type === 'Literal') { 14 | return; 15 | } else { 16 | context.report(node, `The use of $sce.trustAsResourceUrl can be dangerous`); 17 | } 18 | }, 19 | "CallExpression[callee.property.name=trustAsResourceUrl] MemberExpression[property.name=$sce]": function (node) { 20 | var args = node.parent.parent.arguments; 21 | if (args && args[0].type === 'Literal') { 22 | return; 23 | } else { 24 | context.report(node, `The use of $sce.trustAsResourceUrl can be dangerous`); 25 | } 26 | } 27 | }; 28 | } 29 | }; -------------------------------------------------------------------------------- /lib/rules/detect-angular-trustAsUrl-method.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview Rule to detect use of explcility trusted content 3 | * @author Lewis Ardern 4 | */ 5 | 6 | "use strict"; 7 | 8 | module.exports = { 9 | 10 | create: function (context) { 11 | return { 12 | "CallExpression[callee.property.name=trustAsUrl][callee.object.name=$sce]": function (node) { 13 | if (node.arguments[0] && node.arguments[0].type === 'Literal') { 14 | return; 15 | } else { 16 | context.report(node, `The use of $sce.trustAsUrl can be dangerous`); 17 | } 18 | }, 19 | "CallExpression[callee.property.name=trustAsUrl] MemberExpression[property.name=$sce]": function (node) { 20 | var args = node.parent.parent.arguments; 21 | if (args && args[0].type === 'Literal') { 22 | return; 23 | } else { 24 | context.report(node, `The use of $sce.trustAsUrl can be dangerous`); 25 | } 26 | } 27 | }; 28 | } 29 | }; -------------------------------------------------------------------------------- /lib/rules/detect-third-party-angular-translate.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview Rule to detect use of $translateProvider or translateSanitization which can lead to XSS 3 | * @author Lewis Ardern 4 | */ 5 | 6 | "use strict"; 7 | 8 | module.exports = { 9 | create: function(context) { 10 | return { 11 | MemberExpression: function(node) { 12 | if (node.object.name == '$translateProvider' && node.property.name == 'translations') { 13 | context.report(node, "The use of $translateProvider can be dangerous"); 14 | }; 15 | if (node.object.name == '$translateSanitization' && node.property.name == 'useStrategy') { 16 | context.report(node, "If the $translateSanitization.useStrategy is set to null or blank this can be dangerous"); 17 | }; 18 | } 19 | }; 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "eslint-plugin-angularjs-security-rules", 3 | "version": "1.0.6", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@babel/code-frame": { 8 | "version": "7.0.0-beta.36", 9 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.36.tgz", 10 | "integrity": "sha512-sW77BFwJ48YvQp3Gzz5xtAUiXuYOL2aMJKDwiaY3OcvdqBFurtYfOpSa4QrNyDxmOGRFSYzUpabU2m9QrlWE7w==", 11 | "requires": { 12 | "chalk": "2.3.0", 13 | "esutils": "2.0.2", 14 | "js-tokens": "3.0.2" 15 | } 16 | }, 17 | "@babel/helper-function-name": { 18 | "version": "7.0.0-beta.36", 19 | "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.36.tgz", 20 | "integrity": "sha512-/SGPOyifPf20iTrMN+WdlY2MbKa7/o4j7B/4IAsdOusASp2icT+Wcdjf4tjJHaXNX8Pe9bpgVxLNxhRvcf8E5w==", 21 | "requires": { 22 | "@babel/helper-get-function-arity": "7.0.0-beta.36", 23 | "@babel/template": "7.0.0-beta.36", 24 | "@babel/types": "7.0.0-beta.36" 25 | } 26 | }, 27 | "@babel/helper-get-function-arity": { 28 | "version": "7.0.0-beta.36", 29 | "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.36.tgz", 30 | "integrity": "sha512-vPPcx2vsSoDbcyWr9S3nd0FM3B4hEXnt0p1oKpwa08GwK0fSRxa98MyaRGf8suk8frdQlG1P3mDrz5p/Rr3pbA==", 31 | "requires": { 32 | "@babel/types": "7.0.0-beta.36" 33 | } 34 | }, 35 | "@babel/template": { 36 | "version": "7.0.0-beta.36", 37 | "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.0.0-beta.36.tgz", 38 | "integrity": "sha512-mUBi90WRyZ9iVvlWLEdeo8gn/tROyJdjKNC4W5xJTSZL+9MS89rTJSqiaJKXIkxk/YRDL/g/8snrG/O0xl33uA==", 39 | "requires": { 40 | "@babel/code-frame": "7.0.0-beta.36", 41 | "@babel/types": "7.0.0-beta.36", 42 | "babylon": "7.0.0-beta.36", 43 | "lodash": "4.17.4" 44 | } 45 | }, 46 | "@babel/traverse": { 47 | "version": "7.0.0-beta.36", 48 | "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.0.0-beta.36.tgz", 49 | "integrity": "sha512-OTUb6iSKVR/98dGThRJ1BiyfwbuX10BVnkz89IpaerjTPRhDfMBfLsqmzxz5MiywUOW4M0Clta0o7rSxkfcuzw==", 50 | "requires": { 51 | "@babel/code-frame": "7.0.0-beta.36", 52 | "@babel/helper-function-name": "7.0.0-beta.36", 53 | "@babel/types": "7.0.0-beta.36", 54 | "babylon": "7.0.0-beta.36", 55 | "debug": "3.1.0", 56 | "globals": "11.1.0", 57 | "invariant": "2.2.2", 58 | "lodash": "4.17.4" 59 | } 60 | }, 61 | "@babel/types": { 62 | "version": "7.0.0-beta.36", 63 | "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.36.tgz", 64 | "integrity": "sha512-PyAORDO9um9tfnrddXgmWN9e6Sq9qxraQIt5ynqBOSXKA5qvK1kUr+Q3nSzKFdzorsiK+oqcUnAFvEoKxv9D+Q==", 65 | "requires": { 66 | "esutils": "2.0.2", 67 | "lodash": "4.17.4", 68 | "to-fast-properties": "2.0.0" 69 | } 70 | }, 71 | "acorn": { 72 | "version": "5.7.3", 73 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", 74 | "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==" 75 | }, 76 | "acorn-jsx": { 77 | "version": "3.0.1", 78 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", 79 | "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", 80 | "requires": { 81 | "acorn": "^3.0.4" 82 | }, 83 | "dependencies": { 84 | "acorn": { 85 | "version": "3.3.0", 86 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", 87 | "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=" 88 | } 89 | } 90 | }, 91 | "ajv": { 92 | "version": "5.5.2", 93 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", 94 | "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", 95 | "requires": { 96 | "co": "^4.6.0", 97 | "fast-deep-equal": "^1.0.0", 98 | "fast-json-stable-stringify": "^2.0.0", 99 | "json-schema-traverse": "^0.3.0" 100 | } 101 | }, 102 | "ajv-keywords": { 103 | "version": "2.1.1", 104 | "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", 105 | "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=" 106 | }, 107 | "ansi-escapes": { 108 | "version": "3.2.0", 109 | "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", 110 | "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==" 111 | }, 112 | "ansi-regex": { 113 | "version": "2.1.1", 114 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", 115 | "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" 116 | }, 117 | "ansi-styles": { 118 | "version": "2.2.1", 119 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", 120 | "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" 121 | }, 122 | "argparse": { 123 | "version": "1.0.10", 124 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", 125 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", 126 | "requires": { 127 | "sprintf-js": "~1.0.2" 128 | } 129 | }, 130 | "babel-code-frame": { 131 | "version": "6.26.0", 132 | "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", 133 | "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", 134 | "requires": { 135 | "chalk": "^1.1.3", 136 | "esutils": "^2.0.2", 137 | "js-tokens": "^3.0.2" 138 | }, 139 | "dependencies": { 140 | "chalk": { 141 | "version": "1.1.3", 142 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", 143 | "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", 144 | "requires": { 145 | "ansi-styles": "^2.2.1", 146 | "escape-string-regexp": "^1.0.2", 147 | "has-ansi": "^2.0.0", 148 | "strip-ansi": "^3.0.0", 149 | "supports-color": "^2.0.0" 150 | } 151 | }, 152 | "strip-ansi": { 153 | "version": "3.0.1", 154 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", 155 | "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", 156 | "requires": { 157 | "ansi-regex": "^2.0.0" 158 | } 159 | } 160 | } 161 | }, 162 | "babel-eslint": { 163 | "version": "8.2.1", 164 | "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-8.2.1.tgz", 165 | "integrity": "sha512-RzdVOyWKQRUnLXhwLk+eKb4oyW+BykZSkpYwFhM4tnfzAG5OWfvG0w/uyzMp5XKEU0jN82+JefHr39bG2+KhRQ==", 166 | "requires": { 167 | "@babel/code-frame": "7.0.0-beta.36", 168 | "@babel/traverse": "7.0.0-beta.36", 169 | "@babel/types": "7.0.0-beta.36", 170 | "babylon": "7.0.0-beta.36", 171 | "eslint-scope": "3.7.1", 172 | "eslint-visitor-keys": "1.0.0" 173 | } 174 | }, 175 | "babylon": { 176 | "version": "7.0.0-beta.36", 177 | "resolved": "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.36.tgz", 178 | "integrity": "sha512-rw4YdadGwajAMMRl6a5swhQ0JCOOFyaYCfJ0AsmNBD8uBD/r4J8mux7wBaqavvFKqUKQYWOzA1Speams4YDzsQ==" 179 | }, 180 | "balanced-match": { 181 | "version": "1.0.0", 182 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 183 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" 184 | }, 185 | "brace-expansion": { 186 | "version": "1.1.8", 187 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", 188 | "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", 189 | "requires": { 190 | "balanced-match": "1.0.0", 191 | "concat-map": "0.0.1" 192 | } 193 | }, 194 | "browser-stdout": { 195 | "version": "1.3.0", 196 | "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", 197 | "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", 198 | "dev": true 199 | }, 200 | "buffer-from": { 201 | "version": "1.1.1", 202 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", 203 | "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" 204 | }, 205 | "caller-path": { 206 | "version": "0.1.0", 207 | "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", 208 | "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", 209 | "requires": { 210 | "callsites": "^0.2.0" 211 | } 212 | }, 213 | "callsites": { 214 | "version": "0.2.0", 215 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", 216 | "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=" 217 | }, 218 | "chalk": { 219 | "version": "2.3.0", 220 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", 221 | "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", 222 | "requires": { 223 | "ansi-styles": "3.2.0", 224 | "escape-string-regexp": "1.0.5", 225 | "supports-color": "4.5.0" 226 | }, 227 | "dependencies": { 228 | "ansi-styles": { 229 | "version": "3.2.0", 230 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", 231 | "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", 232 | "requires": { 233 | "color-convert": "1.9.1" 234 | } 235 | }, 236 | "supports-color": { 237 | "version": "4.5.0", 238 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", 239 | "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", 240 | "requires": { 241 | "has-flag": "2.0.0" 242 | } 243 | } 244 | } 245 | }, 246 | "chardet": { 247 | "version": "0.4.2", 248 | "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", 249 | "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=" 250 | }, 251 | "circular-json": { 252 | "version": "0.3.3", 253 | "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", 254 | "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==" 255 | }, 256 | "cli-cursor": { 257 | "version": "2.1.0", 258 | "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", 259 | "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", 260 | "requires": { 261 | "restore-cursor": "^2.0.0" 262 | } 263 | }, 264 | "cli-width": { 265 | "version": "2.2.0", 266 | "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", 267 | "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=" 268 | }, 269 | "co": { 270 | "version": "4.6.0", 271 | "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", 272 | "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" 273 | }, 274 | "color-convert": { 275 | "version": "1.9.1", 276 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", 277 | "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", 278 | "requires": { 279 | "color-name": "1.1.3" 280 | } 281 | }, 282 | "color-name": { 283 | "version": "1.1.3", 284 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 285 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" 286 | }, 287 | "commander": { 288 | "version": "2.11.0", 289 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", 290 | "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", 291 | "dev": true 292 | }, 293 | "concat-map": { 294 | "version": "0.0.1", 295 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 296 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" 297 | }, 298 | "concat-stream": { 299 | "version": "1.6.2", 300 | "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", 301 | "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", 302 | "requires": { 303 | "buffer-from": "^1.0.0", 304 | "inherits": "^2.0.3", 305 | "readable-stream": "^2.2.2", 306 | "typedarray": "^0.0.6" 307 | } 308 | }, 309 | "core-util-is": { 310 | "version": "1.0.2", 311 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 312 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 313 | }, 314 | "cross-spawn": { 315 | "version": "5.1.0", 316 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", 317 | "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", 318 | "requires": { 319 | "lru-cache": "^4.0.1", 320 | "shebang-command": "^1.2.0", 321 | "which": "^1.2.9" 322 | } 323 | }, 324 | "debug": { 325 | "version": "3.1.0", 326 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", 327 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", 328 | "requires": { 329 | "ms": "2.0.0" 330 | } 331 | }, 332 | "deep-is": { 333 | "version": "0.1.3", 334 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", 335 | "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" 336 | }, 337 | "diff": { 338 | "version": "3.3.1", 339 | "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", 340 | "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", 341 | "dev": true 342 | }, 343 | "doctrine": { 344 | "version": "2.1.0", 345 | "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", 346 | "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", 347 | "requires": { 348 | "esutils": "^2.0.2" 349 | } 350 | }, 351 | "escape-string-regexp": { 352 | "version": "1.0.5", 353 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 354 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" 355 | }, 356 | "eslint": { 357 | "version": "4.18.2", 358 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.18.2.tgz", 359 | "integrity": "sha512-qy4i3wODqKMYfz9LUI8N2qYDkHkoieTbiHpMrYUI/WbjhXJQr7lI4VngixTgaG+yHX+NBCv7nW4hA0ShbvaNKw==", 360 | "requires": { 361 | "ajv": "^5.3.0", 362 | "babel-code-frame": "^6.22.0", 363 | "chalk": "^2.1.0", 364 | "concat-stream": "^1.6.0", 365 | "cross-spawn": "^5.1.0", 366 | "debug": "^3.1.0", 367 | "doctrine": "^2.1.0", 368 | "eslint-scope": "^3.7.1", 369 | "eslint-visitor-keys": "^1.0.0", 370 | "espree": "^3.5.2", 371 | "esquery": "^1.0.0", 372 | "esutils": "^2.0.2", 373 | "file-entry-cache": "^2.0.0", 374 | "functional-red-black-tree": "^1.0.1", 375 | "glob": "^7.1.2", 376 | "globals": "^11.0.1", 377 | "ignore": "^3.3.3", 378 | "imurmurhash": "^0.1.4", 379 | "inquirer": "^3.0.6", 380 | "is-resolvable": "^1.0.0", 381 | "js-yaml": "^3.9.1", 382 | "json-stable-stringify-without-jsonify": "^1.0.1", 383 | "levn": "^0.3.0", 384 | "lodash": "^4.17.4", 385 | "minimatch": "^3.0.2", 386 | "mkdirp": "^0.5.1", 387 | "natural-compare": "^1.4.0", 388 | "optionator": "^0.8.2", 389 | "path-is-inside": "^1.0.2", 390 | "pluralize": "^7.0.0", 391 | "progress": "^2.0.0", 392 | "require-uncached": "^1.0.3", 393 | "semver": "^5.3.0", 394 | "strip-ansi": "^4.0.0", 395 | "strip-json-comments": "~2.0.1", 396 | "table": "4.0.2", 397 | "text-table": "~0.2.0" 398 | } 399 | }, 400 | "eslint-scope": { 401 | "version": "3.7.1", 402 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", 403 | "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", 404 | "requires": { 405 | "esrecurse": "4.2.0", 406 | "estraverse": "4.2.0" 407 | } 408 | }, 409 | "eslint-visitor-keys": { 410 | "version": "1.0.0", 411 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", 412 | "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==" 413 | }, 414 | "espree": { 415 | "version": "3.5.4", 416 | "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", 417 | "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", 418 | "requires": { 419 | "acorn": "^5.5.0", 420 | "acorn-jsx": "^3.0.0" 421 | } 422 | }, 423 | "esprima": { 424 | "version": "4.0.1", 425 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", 426 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" 427 | }, 428 | "esquery": { 429 | "version": "1.0.1", 430 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", 431 | "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", 432 | "requires": { 433 | "estraverse": "^4.0.0" 434 | } 435 | }, 436 | "esrecurse": { 437 | "version": "4.2.0", 438 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz", 439 | "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=", 440 | "requires": { 441 | "estraverse": "4.2.0", 442 | "object-assign": "4.1.1" 443 | } 444 | }, 445 | "estraverse": { 446 | "version": "4.2.0", 447 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", 448 | "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=" 449 | }, 450 | "esutils": { 451 | "version": "2.0.2", 452 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", 453 | "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=" 454 | }, 455 | "external-editor": { 456 | "version": "2.2.0", 457 | "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", 458 | "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", 459 | "requires": { 460 | "chardet": "^0.4.0", 461 | "iconv-lite": "^0.4.17", 462 | "tmp": "^0.0.33" 463 | } 464 | }, 465 | "fast-deep-equal": { 466 | "version": "1.1.0", 467 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", 468 | "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=" 469 | }, 470 | "fast-json-stable-stringify": { 471 | "version": "2.0.0", 472 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", 473 | "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" 474 | }, 475 | "fast-levenshtein": { 476 | "version": "2.0.6", 477 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 478 | "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" 479 | }, 480 | "figures": { 481 | "version": "2.0.0", 482 | "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", 483 | "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", 484 | "requires": { 485 | "escape-string-regexp": "^1.0.5" 486 | } 487 | }, 488 | "file-entry-cache": { 489 | "version": "2.0.0", 490 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", 491 | "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", 492 | "requires": { 493 | "flat-cache": "^1.2.1", 494 | "object-assign": "^4.0.1" 495 | } 496 | }, 497 | "flat-cache": { 498 | "version": "1.3.4", 499 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz", 500 | "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==", 501 | "requires": { 502 | "circular-json": "^0.3.1", 503 | "graceful-fs": "^4.1.2", 504 | "rimraf": "~2.6.2", 505 | "write": "^0.2.1" 506 | } 507 | }, 508 | "fs.realpath": { 509 | "version": "1.0.0", 510 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 511 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" 512 | }, 513 | "functional-red-black-tree": { 514 | "version": "1.0.1", 515 | "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", 516 | "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" 517 | }, 518 | "glob": { 519 | "version": "7.1.2", 520 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", 521 | "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", 522 | "requires": { 523 | "fs.realpath": "1.0.0", 524 | "inflight": "1.0.6", 525 | "inherits": "2.0.3", 526 | "minimatch": "3.0.4", 527 | "once": "1.4.0", 528 | "path-is-absolute": "1.0.1" 529 | } 530 | }, 531 | "globals": { 532 | "version": "11.1.0", 533 | "resolved": "https://registry.npmjs.org/globals/-/globals-11.1.0.tgz", 534 | "integrity": "sha512-uEuWt9mqTlPDwSqi+sHjD4nWU/1N+q0fiWI9T1mZpD2UENqX20CFD5T/ziLZvztPaBKl7ZylUi1q6Qfm7E2CiQ==" 535 | }, 536 | "graceful-fs": { 537 | "version": "4.1.15", 538 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", 539 | "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==" 540 | }, 541 | "growl": { 542 | "version": "1.10.3", 543 | "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", 544 | "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", 545 | "dev": true 546 | }, 547 | "has-ansi": { 548 | "version": "2.0.0", 549 | "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", 550 | "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", 551 | "requires": { 552 | "ansi-regex": "^2.0.0" 553 | } 554 | }, 555 | "has-flag": { 556 | "version": "2.0.0", 557 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", 558 | "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=" 559 | }, 560 | "he": { 561 | "version": "1.1.1", 562 | "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", 563 | "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", 564 | "dev": true 565 | }, 566 | "iconv-lite": { 567 | "version": "0.4.24", 568 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 569 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 570 | "requires": { 571 | "safer-buffer": ">= 2.1.2 < 3" 572 | } 573 | }, 574 | "ignore": { 575 | "version": "3.3.10", 576 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", 577 | "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==" 578 | }, 579 | "imurmurhash": { 580 | "version": "0.1.4", 581 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 582 | "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" 583 | }, 584 | "inflight": { 585 | "version": "1.0.6", 586 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 587 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 588 | "requires": { 589 | "once": "1.4.0", 590 | "wrappy": "1.0.2" 591 | } 592 | }, 593 | "inherits": { 594 | "version": "2.0.3", 595 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 596 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 597 | }, 598 | "inquirer": { 599 | "version": "3.3.0", 600 | "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", 601 | "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", 602 | "requires": { 603 | "ansi-escapes": "^3.0.0", 604 | "chalk": "^2.0.0", 605 | "cli-cursor": "^2.1.0", 606 | "cli-width": "^2.0.0", 607 | "external-editor": "^2.0.4", 608 | "figures": "^2.0.0", 609 | "lodash": "^4.3.0", 610 | "mute-stream": "0.0.7", 611 | "run-async": "^2.2.0", 612 | "rx-lite": "^4.0.8", 613 | "rx-lite-aggregates": "^4.0.8", 614 | "string-width": "^2.1.0", 615 | "strip-ansi": "^4.0.0", 616 | "through": "^2.3.6" 617 | } 618 | }, 619 | "invariant": { 620 | "version": "2.2.2", 621 | "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz", 622 | "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=", 623 | "requires": { 624 | "loose-envify": "1.3.1" 625 | } 626 | }, 627 | "is-fullwidth-code-point": { 628 | "version": "2.0.0", 629 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 630 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" 631 | }, 632 | "is-promise": { 633 | "version": "2.1.0", 634 | "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", 635 | "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" 636 | }, 637 | "is-resolvable": { 638 | "version": "1.1.0", 639 | "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", 640 | "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==" 641 | }, 642 | "isarray": { 643 | "version": "1.0.0", 644 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 645 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" 646 | }, 647 | "isexe": { 648 | "version": "2.0.0", 649 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 650 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" 651 | }, 652 | "js-tokens": { 653 | "version": "3.0.2", 654 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", 655 | "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" 656 | }, 657 | "js-yaml": { 658 | "version": "3.13.1", 659 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", 660 | "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", 661 | "requires": { 662 | "argparse": "^1.0.7", 663 | "esprima": "^4.0.0" 664 | } 665 | }, 666 | "json-schema-traverse": { 667 | "version": "0.3.1", 668 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", 669 | "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" 670 | }, 671 | "json-stable-stringify-without-jsonify": { 672 | "version": "1.0.1", 673 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", 674 | "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=" 675 | }, 676 | "levn": { 677 | "version": "0.3.0", 678 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", 679 | "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", 680 | "requires": { 681 | "prelude-ls": "~1.1.2", 682 | "type-check": "~0.3.2" 683 | } 684 | }, 685 | "lodash": { 686 | "version": "4.17.4", 687 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", 688 | "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" 689 | }, 690 | "loose-envify": { 691 | "version": "1.3.1", 692 | "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", 693 | "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", 694 | "requires": { 695 | "js-tokens": "3.0.2" 696 | } 697 | }, 698 | "lru-cache": { 699 | "version": "4.1.5", 700 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", 701 | "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", 702 | "requires": { 703 | "pseudomap": "^1.0.2", 704 | "yallist": "^2.1.2" 705 | } 706 | }, 707 | "mimic-fn": { 708 | "version": "1.2.0", 709 | "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", 710 | "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==" 711 | }, 712 | "minimatch": { 713 | "version": "3.0.4", 714 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 715 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 716 | "requires": { 717 | "brace-expansion": "1.1.8" 718 | } 719 | }, 720 | "minimist": { 721 | "version": "0.0.8", 722 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", 723 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" 724 | }, 725 | "mkdirp": { 726 | "version": "0.5.1", 727 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", 728 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", 729 | "requires": { 730 | "minimist": "0.0.8" 731 | } 732 | }, 733 | "mocha": { 734 | "version": "4.1.0", 735 | "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", 736 | "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", 737 | "dev": true, 738 | "requires": { 739 | "browser-stdout": "1.3.0", 740 | "commander": "2.11.0", 741 | "debug": "3.1.0", 742 | "diff": "3.3.1", 743 | "escape-string-regexp": "1.0.5", 744 | "glob": "7.1.2", 745 | "growl": "1.10.3", 746 | "he": "1.1.1", 747 | "mkdirp": "0.5.1", 748 | "supports-color": "4.4.0" 749 | }, 750 | "dependencies": { 751 | "supports-color": { 752 | "version": "4.4.0", 753 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", 754 | "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", 755 | "dev": true, 756 | "requires": { 757 | "has-flag": "2.0.0" 758 | } 759 | } 760 | } 761 | }, 762 | "ms": { 763 | "version": "2.0.0", 764 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 765 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 766 | }, 767 | "mute-stream": { 768 | "version": "0.0.7", 769 | "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", 770 | "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" 771 | }, 772 | "natural-compare": { 773 | "version": "1.4.0", 774 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", 775 | "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" 776 | }, 777 | "object-assign": { 778 | "version": "4.1.1", 779 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 780 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" 781 | }, 782 | "once": { 783 | "version": "1.4.0", 784 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 785 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 786 | "requires": { 787 | "wrappy": "1.0.2" 788 | } 789 | }, 790 | "onetime": { 791 | "version": "2.0.1", 792 | "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", 793 | "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", 794 | "requires": { 795 | "mimic-fn": "^1.0.0" 796 | } 797 | }, 798 | "optionator": { 799 | "version": "0.8.2", 800 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", 801 | "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", 802 | "requires": { 803 | "deep-is": "~0.1.3", 804 | "fast-levenshtein": "~2.0.4", 805 | "levn": "~0.3.0", 806 | "prelude-ls": "~1.1.2", 807 | "type-check": "~0.3.2", 808 | "wordwrap": "~1.0.0" 809 | } 810 | }, 811 | "os-tmpdir": { 812 | "version": "1.0.2", 813 | "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", 814 | "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" 815 | }, 816 | "path-is-absolute": { 817 | "version": "1.0.1", 818 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 819 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" 820 | }, 821 | "path-is-inside": { 822 | "version": "1.0.2", 823 | "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", 824 | "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=" 825 | }, 826 | "pluralize": { 827 | "version": "7.0.0", 828 | "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", 829 | "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==" 830 | }, 831 | "prelude-ls": { 832 | "version": "1.1.2", 833 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", 834 | "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" 835 | }, 836 | "process-nextick-args": { 837 | "version": "2.0.1", 838 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", 839 | "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" 840 | }, 841 | "progress": { 842 | "version": "2.0.3", 843 | "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", 844 | "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" 845 | }, 846 | "pseudomap": { 847 | "version": "1.0.2", 848 | "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", 849 | "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" 850 | }, 851 | "readable-stream": { 852 | "version": "2.3.6", 853 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", 854 | "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", 855 | "requires": { 856 | "core-util-is": "~1.0.0", 857 | "inherits": "~2.0.3", 858 | "isarray": "~1.0.0", 859 | "process-nextick-args": "~2.0.0", 860 | "safe-buffer": "~5.1.1", 861 | "string_decoder": "~1.1.1", 862 | "util-deprecate": "~1.0.1" 863 | } 864 | }, 865 | "require-uncached": { 866 | "version": "1.0.3", 867 | "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", 868 | "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", 869 | "requires": { 870 | "caller-path": "^0.1.0", 871 | "resolve-from": "^1.0.0" 872 | } 873 | }, 874 | "requireindex": { 875 | "version": "1.1.0", 876 | "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.1.0.tgz", 877 | "integrity": "sha1-5UBLgVV+91225JxacgBIk/4D4WI=" 878 | }, 879 | "resolve-from": { 880 | "version": "1.0.1", 881 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", 882 | "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=" 883 | }, 884 | "restore-cursor": { 885 | "version": "2.0.0", 886 | "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", 887 | "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", 888 | "requires": { 889 | "onetime": "^2.0.0", 890 | "signal-exit": "^3.0.2" 891 | } 892 | }, 893 | "rimraf": { 894 | "version": "2.6.3", 895 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", 896 | "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", 897 | "requires": { 898 | "glob": "^7.1.3" 899 | }, 900 | "dependencies": { 901 | "glob": { 902 | "version": "7.1.4", 903 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", 904 | "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", 905 | "requires": { 906 | "fs.realpath": "^1.0.0", 907 | "inflight": "^1.0.4", 908 | "inherits": "2", 909 | "minimatch": "^3.0.4", 910 | "once": "^1.3.0", 911 | "path-is-absolute": "^1.0.0" 912 | } 913 | } 914 | } 915 | }, 916 | "run-async": { 917 | "version": "2.3.0", 918 | "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", 919 | "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", 920 | "requires": { 921 | "is-promise": "^2.1.0" 922 | } 923 | }, 924 | "rx-lite": { 925 | "version": "4.0.8", 926 | "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", 927 | "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=" 928 | }, 929 | "rx-lite-aggregates": { 930 | "version": "4.0.8", 931 | "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", 932 | "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", 933 | "requires": { 934 | "rx-lite": "*" 935 | } 936 | }, 937 | "safe-buffer": { 938 | "version": "5.1.2", 939 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 940 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 941 | }, 942 | "safer-buffer": { 943 | "version": "2.1.2", 944 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 945 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 946 | }, 947 | "semver": { 948 | "version": "5.7.0", 949 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", 950 | "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" 951 | }, 952 | "shebang-command": { 953 | "version": "1.2.0", 954 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", 955 | "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", 956 | "requires": { 957 | "shebang-regex": "^1.0.0" 958 | } 959 | }, 960 | "shebang-regex": { 961 | "version": "1.0.0", 962 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", 963 | "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" 964 | }, 965 | "signal-exit": { 966 | "version": "3.0.2", 967 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", 968 | "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" 969 | }, 970 | "slice-ansi": { 971 | "version": "1.0.0", 972 | "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", 973 | "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", 974 | "requires": { 975 | "is-fullwidth-code-point": "^2.0.0" 976 | } 977 | }, 978 | "sprintf-js": { 979 | "version": "1.0.3", 980 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", 981 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" 982 | }, 983 | "string-width": { 984 | "version": "2.1.1", 985 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", 986 | "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", 987 | "requires": { 988 | "is-fullwidth-code-point": "^2.0.0", 989 | "strip-ansi": "^4.0.0" 990 | } 991 | }, 992 | "string_decoder": { 993 | "version": "1.1.1", 994 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 995 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 996 | "requires": { 997 | "safe-buffer": "~5.1.0" 998 | } 999 | }, 1000 | "strip-ansi": { 1001 | "version": "4.0.0", 1002 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", 1003 | "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", 1004 | "requires": { 1005 | "ansi-regex": "^3.0.0" 1006 | }, 1007 | "dependencies": { 1008 | "ansi-regex": { 1009 | "version": "3.0.0", 1010 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", 1011 | "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" 1012 | } 1013 | } 1014 | }, 1015 | "strip-json-comments": { 1016 | "version": "2.0.1", 1017 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", 1018 | "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" 1019 | }, 1020 | "supports-color": { 1021 | "version": "2.0.0", 1022 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", 1023 | "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" 1024 | }, 1025 | "table": { 1026 | "version": "4.0.2", 1027 | "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", 1028 | "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", 1029 | "requires": { 1030 | "ajv": "^5.2.3", 1031 | "ajv-keywords": "^2.1.0", 1032 | "chalk": "^2.1.0", 1033 | "lodash": "^4.17.4", 1034 | "slice-ansi": "1.0.0", 1035 | "string-width": "^2.1.1" 1036 | } 1037 | }, 1038 | "text-table": { 1039 | "version": "0.2.0", 1040 | "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", 1041 | "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" 1042 | }, 1043 | "through": { 1044 | "version": "2.3.8", 1045 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", 1046 | "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" 1047 | }, 1048 | "tmp": { 1049 | "version": "0.0.33", 1050 | "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", 1051 | "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", 1052 | "requires": { 1053 | "os-tmpdir": "~1.0.2" 1054 | } 1055 | }, 1056 | "to-fast-properties": { 1057 | "version": "2.0.0", 1058 | "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", 1059 | "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" 1060 | }, 1061 | "type-check": { 1062 | "version": "0.3.2", 1063 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", 1064 | "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", 1065 | "requires": { 1066 | "prelude-ls": "~1.1.2" 1067 | } 1068 | }, 1069 | "typedarray": { 1070 | "version": "0.0.6", 1071 | "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", 1072 | "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" 1073 | }, 1074 | "util-deprecate": { 1075 | "version": "1.0.2", 1076 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 1077 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" 1078 | }, 1079 | "which": { 1080 | "version": "1.3.1", 1081 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", 1082 | "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", 1083 | "requires": { 1084 | "isexe": "^2.0.0" 1085 | } 1086 | }, 1087 | "wordwrap": { 1088 | "version": "1.0.0", 1089 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", 1090 | "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" 1091 | }, 1092 | "wrappy": { 1093 | "version": "1.0.2", 1094 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1095 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" 1096 | }, 1097 | "write": { 1098 | "version": "0.2.1", 1099 | "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", 1100 | "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", 1101 | "requires": { 1102 | "mkdirp": "^0.5.1" 1103 | } 1104 | }, 1105 | "yallist": { 1106 | "version": "2.1.2", 1107 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", 1108 | "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" 1109 | } 1110 | } 1111 | } 1112 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "eslint-plugin-angularjs-security-rules", 3 | "version": "1.0.8", 4 | "description": "ESLint plugin that contains AngularJS rules", 5 | "main": "./lib/index.js", 6 | "directories": { 7 | "test": "tests" 8 | }, 9 | "scripts": { 10 | "test": "./node_modules/.bin/mocha --recursive tests/rules" 11 | }, 12 | "keywords": [ 13 | "security", 14 | "eslint", 15 | "eslint-plugin", 16 | "Angular", 17 | "AngularJS", 18 | "lint" 19 | ], 20 | "author": "Lewis Ardern", 21 | "license": "MIT", 22 | "dependencies": { 23 | "babel-eslint": "^8.2.1", 24 | "eslint": "^4.16.0", 25 | "requireindex": "^1.1.0" 26 | }, 27 | "devDependencies": { 28 | "mocha": "^4.1.0" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /tests/rules/detect-angular-element-methods.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview Test for detect-angular-element-methods rule 3 | * @author Lewis Ardern 4 | */ 5 | "use strict"; 6 | 7 | //------------------------------------------------------------------------------ 8 | // Requirements 9 | //------------------------------------------------------------------------------ 10 | 11 | var rule = require("../../lib/rules/detect-angular-element-methods"); 12 | var RuleTester = require('eslint').RuleTester; 13 | 14 | //------------------------------------------------------------------------------ 15 | // Tests 16 | //------------------------------------------------------------------------------ 17 | 18 | var eslintTester = new RuleTester(); 19 | 20 | eslintTester.run("detect-angular-element-methods", rule, { 21 | valid: [ 22 | { code: "foo()" } // no need to look for valid as we are just doing detection 23 | ], 24 | invalid: [ 25 | { 26 | code: "angular.element()", 27 | errors: [ 28 | { message: "Use of angular.element can lead to XSS if after,append,html,prepend,replaceWith,wrap are used with user-input" } 29 | ], 30 | } 31 | ] 32 | }); 33 | -------------------------------------------------------------------------------- /tests/rules/detect-angular-open-redirect.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview Test for detect-angular-open-redirect rule 3 | * @author Lewis Ardern 4 | */ 5 | "use strict"; 6 | 7 | //------------------------------------------------------------------------------ 8 | // Requirements 9 | //------------------------------------------------------------------------------ 10 | 11 | var rule = require("../../lib/rules/detect-angular-open-redirect"); 12 | var RuleTester = require('eslint').RuleTester; 13 | 14 | //------------------------------------------------------------------------------ 15 | // Tests 16 | //------------------------------------------------------------------------------ 17 | 18 | var eslintTester = new RuleTester(); 19 | 20 | eslintTester.run("detect-angular-open-redirect", rule, { 21 | valid: [ 22 | { code: "$location.location.location = test" } 23 | ], 24 | invalid: [ 25 | { 26 | code: "$window.location.href = userInput", 27 | errors: [ 28 | { message: "Use of $window.location.href can lead to open-redirect" } 29 | ] 30 | }, 31 | ] 32 | }); 33 | -------------------------------------------------------------------------------- /tests/rules/detect-angular-orderBy-expressions.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview Test for detect-angular-sce-disabled rule 3 | * @author Lewis Ardern 4 | */ 5 | "use strict"; 6 | 7 | //------------------------------------------------------------------------------ 8 | // Requirements 9 | //------------------------------------------------------------------------------ 10 | 11 | var rule = require("../../lib/rules/detect-angular-orderBy-expressions"); 12 | var RuleTester = require('eslint').RuleTester; 13 | 14 | //------------------------------------------------------------------------------ 15 | // Tests 16 | //------------------------------------------------------------------------------ 17 | 18 | var eslintTester = new RuleTester(); 19 | 20 | eslintTester.run("detect-angular-orderBy-expressions", rule, { 21 | valid: [ 22 | { code: "$filter('filter')(array, expression, comparator, anyPropertyKey)" } // no need to look for valid as we are just doing detection 23 | ], 24 | invalid: [ 25 | { 26 | code: "$filter('orderBy')(collection, expression, reverse, comparator)", 27 | errors: [ 28 | { message: "The method $filter('orderBy') can be dangerous" } 29 | ], 30 | } 31 | ] 32 | }); 33 | -------------------------------------------------------------------------------- /tests/rules/detect-angular-resource-loading.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview Test for detect-angular-resource-loading rule 3 | * @author Lewis Ardern 4 | */ 5 | "use strict"; 6 | 7 | //------------------------------------------------------------------------------ 8 | // Requirements 9 | //------------------------------------------------------------------------------ 10 | 11 | var rule = require("../../lib/rules/detect-angular-resource-loading"); 12 | var RuleTester = require('eslint').RuleTester; 13 | 14 | //------------------------------------------------------------------------------ 15 | // Tests 16 | //------------------------------------------------------------------------------ 17 | 18 | var eslintTester = new RuleTester(); 19 | 20 | eslintTester.run("detect-angular-resource-loading", rule, { 21 | valid: [ 22 | { code: "$scope.$foo()" } 23 | ], 24 | invalid: [ 25 | { 26 | code: "$sceDelegateProvider.resourceUrlWhitelist([ '**' ]);", 27 | errors: [ 28 | { message: "$sceDelegateProvider whitelisting can be introduce security issues" } 29 | ] 30 | }, 31 | ] 32 | }); 33 | -------------------------------------------------------------------------------- /tests/rules/detect-angular-sce-disabled.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview Test for detect-angular-sce-disabled rule 3 | * @author Lewis Ardern 4 | */ 5 | "use strict"; 6 | 7 | //------------------------------------------------------------------------------ 8 | // Requirements 9 | //------------------------------------------------------------------------------ 10 | 11 | var rule = require("../../lib/rules/detect-angular-sce-disabled"); 12 | var RuleTester = require('eslint').RuleTester; 13 | 14 | //------------------------------------------------------------------------------ 15 | // Tests 16 | //------------------------------------------------------------------------------ 17 | 18 | var eslintTester = new RuleTester(); 19 | 20 | eslintTester.run("detect-angular-sce-disabled", rule, { 21 | valid: [ 22 | { code: "$sceProvider.enabled(true)" } 23 | ], 24 | invalid: [ 25 | { 26 | code: "$sceProvider.enabled(false)", 27 | errors: [ 28 | { message: "$sceProvider is set to false" } 29 | ] 30 | }, 31 | ] 32 | }); 33 | -------------------------------------------------------------------------------- /tests/rules/detect-angular-scope-expressions.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview Test for detect-angular-scope-expressions rule 3 | * @author Lewis Ardern 4 | */ 5 | "use strict"; 6 | 7 | //------------------------------------------------------------------------------ 8 | // Requirements 9 | //------------------------------------------------------------------------------ 10 | 11 | var rule = require("../../lib/rules/detect-angular-scope-expressions"); 12 | var RuleTester = require('eslint').RuleTester; 13 | 14 | //------------------------------------------------------------------------------ 15 | // Tests 16 | //------------------------------------------------------------------------------ 17 | 18 | var eslintTester = new RuleTester(); 19 | 20 | eslintTester.run("detect-angular-scope-expressions", rule, { 21 | valid: [ 22 | { code: "foo()" } // no need to look for valid as we are just doing detection 23 | ], 24 | invalid: [ 25 | { 26 | code: "$scope.$evalAsync('result = name.' + userInput);", 27 | errors: [ 28 | { message: "The method $evalAsync can be dangerous" } 29 | ], 30 | }, 31 | { 32 | code: "$scope.$eval('test = name.' + userInput);", 33 | errors: [ 34 | { message: "The method $eval can be dangerous" } 35 | ] 36 | }, 37 | { 38 | code: "$scope.$apply('test = name.' + userInput);", 39 | errors: [ 40 | { message: "The method $apply can be dangerous" } 41 | ] 42 | }, 43 | { 44 | code: "$scope.$applyAsync('test = name.' + userInput);", 45 | errors: [ 46 | { message: "The method $applyAsync can be dangerous" } 47 | ] 48 | }, 49 | { 50 | code: "$scope.$watch(watchExpression, listener, [objectEquality]);", 51 | errors: [ 52 | { message: "The method $watch can be dangerous" } 53 | ] 54 | }, 55 | { 56 | code: "$scope.$watchGroup(watchExpression, listener);", 57 | errors: [ 58 | { message: "The method $watchGroup can be dangerous" } 59 | ] 60 | }, 61 | { 62 | code: "$scope.$watchCollection(obj, listener);", 63 | errors: [ 64 | { message: "The method $watchCollection can be dangerous" } 65 | ] 66 | } 67 | ] 68 | }); 69 | -------------------------------------------------------------------------------- /tests/rules/detect-angular-service-expressions.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview Test for detect-angular-service-expressions rule 3 | * @author Lewis Ardern 4 | */ 5 | "use strict"; 6 | 7 | //------------------------------------------------------------------------------ 8 | // Requirements 9 | //------------------------------------------------------------------------------ 10 | 11 | var rule = require("../../lib/rules/detect-angular-service-expressions"); 12 | var RuleTester = require('eslint').RuleTester; 13 | 14 | //------------------------------------------------------------------------------ 15 | // Tests 16 | //------------------------------------------------------------------------------ 17 | 18 | var eslintTester = new RuleTester(); 19 | 20 | eslintTester.run("detect-angular-service-expressions", rule, { 21 | valid: [ 22 | { code: "foo()" } // no need to look for valid as we are just doing detection 23 | ], 24 | invalid: [ 25 | { 26 | code: "$compile(element, transclude, maxPriority);", 27 | errors: [ 28 | { message: "The method $compile can be dangerous" } 29 | ], 30 | }, 31 | { 32 | code: "$parse(expression);", 33 | errors: [ 34 | { message: "The method $parse can be dangerous" } 35 | ] 36 | }, 37 | { 38 | code: "$interpolate(text, [mustHaveExpression], [trustedContext], [allOrNothing]);", 39 | errors: [ 40 | { message: "The method $interpolate can be dangerous" } 41 | ] 42 | } 43 | ] 44 | }); 45 | -------------------------------------------------------------------------------- /tests/rules/detect-angular-trustAs-methods.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview Test for detect-angular-trustAs-methods 3 | * @author Lewis Ardern 4 | */ 5 | "use strict"; 6 | 7 | //------------------------------------------------------------------------------ 8 | // Requirements 9 | //------------------------------------------------------------------------------ 10 | 11 | var rule = require("../../lib/rules/detect-angular-trustAs-methods"); 12 | var RuleTester = require('eslint').RuleTester; 13 | 14 | //------------------------------------------------------------------------------ 15 | // Tests 16 | //------------------------------------------------------------------------------ 17 | 18 | var eslintTester = new RuleTester(); 19 | 20 | eslintTester.run("detect-angular-trustAs-methods", rule, { 21 | valid: [ 22 | { code: "this.$sce.trustAs($sce.HTML, 'stringLiteralValue');" }, // string literals are OK 23 | { code: "$sce.trustAs($sce.HTML, 'stringLiteralValue');" }, 24 | { code: "$sce.ParseAsHtml()" }, 25 | { code: "this.$sce.ParseAsHtml()" } // no need to look for valid as we are just doing detection 26 | ], 27 | invalid: [ 28 | { 29 | code: "$sce.trustAs($sce.HTML, value);", 30 | errors: [ 31 | { message: "The use of $sce.trustAs can be dangerous" } 32 | ], 33 | }, 34 | { 35 | code: "this.$sce.trustAs($sce.HTML, value);", 36 | errors: [ 37 | { message: "The use of $sce.trustAs can be dangerous" } 38 | ], 39 | }, 40 | { 41 | code: "$sce.trustAs($sce.CSS, value);", 42 | errors: [ 43 | { message: "The use of $sce.trustAs can be dangerous" } 44 | ], 45 | }, 46 | { 47 | code: "$sce.trustAs($sce.JS, value);", 48 | errors: [ 49 | { message: "The use of $sce.trustAs can be dangerous" } 50 | ], 51 | }, 52 | { 53 | code: "this.$sce.trustAs($sce.JS, value);", 54 | errors: [ 55 | { message: "The use of $sce.trustAs can be dangerous" } 56 | ], 57 | }, 58 | { 59 | code: "$sce.trustAs($sce.RESOURCE_URL, value);", 60 | errors: [ 61 | { message: "The use of $sce.trustAs can be dangerous" } 62 | ], 63 | }, 64 | { 65 | code: "this.$sce.trustAs($sce.RESOURCE_URL, value);", 66 | errors: [ 67 | { message: "The use of $sce.trustAs can be dangerous" } 68 | ], 69 | }, 70 | { 71 | code: "this.$sce.trustAs($sce.URL, value);", 72 | errors: [ 73 | { message: "The use of $sce.trustAs can be dangerous" } 74 | ], 75 | }, 76 | { 77 | code: "$sce.trustAs($sce.URL, value);", 78 | errors: [ 79 | { message: "The use of $sce.trustAs can be dangerous" } 80 | ], 81 | } 82 | ] 83 | }); 84 | -------------------------------------------------------------------------------- /tests/rules/detect-angular-trustAsCss-method.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview Test for detect-angular-trustAs-methods 3 | * @author Lewis Ardern 4 | */ 5 | "use strict"; 6 | 7 | //------------------------------------------------------------------------------ 8 | // Requirements 9 | //------------------------------------------------------------------------------ 10 | 11 | var rule = require("../../lib/rules/detect-angular-trustAsCss-method"); 12 | var RuleTester = require('eslint').RuleTester; 13 | 14 | //------------------------------------------------------------------------------ 15 | // Tests 16 | //------------------------------------------------------------------------------ 17 | 18 | var eslintTester = new RuleTester(); 19 | 20 | eslintTester.run("detect-angular-trustAsCss-method", rule, { 21 | valid: [ 22 | { code: "$sce.trustAsCss('stringLiteral');" }, // string literals are OK 23 | { code: "$sce.ParseAsHtml()" }, 24 | { code: "this.$sce.ParseAsHtml()" } // no need to look for valid as we are just doing detection 25 | ], 26 | invalid: [ 27 | { 28 | code: "$sce.trustAsCss(value);", 29 | errors: [ 30 | { message: "The use of $sce.trustAsCss can be dangerous" } 31 | ], 32 | }, 33 | { 34 | code: "this.$sce.trustAsCss(value);", 35 | errors: [ 36 | { message: "The use of $sce.trustAsCss can be dangerous" } 37 | ], 38 | } 39 | ] 40 | }); 41 | -------------------------------------------------------------------------------- /tests/rules/detect-angular-trustAsHtml-method.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview Test for detect-angular-trustAs-methods 3 | * @author Lewis Ardern 4 | */ 5 | "use strict"; 6 | 7 | //------------------------------------------------------------------------------ 8 | // Requirements 9 | //------------------------------------------------------------------------------ 10 | 11 | var rule = require("../../lib/rules/detect-angular-trustAsHtml-method"); 12 | var RuleTester = require('eslint').RuleTester; 13 | 14 | //------------------------------------------------------------------------------ 15 | // Tests 16 | //------------------------------------------------------------------------------ 17 | 18 | var eslintTester = new RuleTester(); 19 | 20 | eslintTester.run("detect-angular-trustAsHtml-method", rule, { 21 | valid: [ 22 | { code: "$sce.trustAsHtml('stringLiteral');" }, // string literals are OK 23 | { code: "$sce.ParseAsHtml()" }, 24 | { code: "this.$sce.ParseAsHtml()" } // no need to look for valid as we are just doing detection 25 | ], 26 | invalid: [ 27 | { 28 | code: "$sce.trustAsHtml(value);", 29 | errors: [ 30 | { message: "The use of $sce.trustAsHtml can be dangerous" } 31 | ], 32 | }, 33 | { 34 | code: "this.$sce.trustAsHtml(value);", 35 | errors: [ 36 | { message: "The use of $sce.trustAsHtml can be dangerous" } 37 | ], 38 | }, 39 | ] 40 | }); 41 | -------------------------------------------------------------------------------- /tests/rules/detect-angular-trustAsJs-method.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview Test for detect-angular-trustAs-methods 3 | * @author Lewis Ardern 4 | */ 5 | "use strict"; 6 | 7 | //------------------------------------------------------------------------------ 8 | // Requirements 9 | //------------------------------------------------------------------------------ 10 | 11 | var rule = require("../../lib/rules/detect-angular-trustAsJs-method"); 12 | var RuleTester = require('eslint').RuleTester; 13 | 14 | //------------------------------------------------------------------------------ 15 | // Tests 16 | //------------------------------------------------------------------------------ 17 | 18 | var eslintTester = new RuleTester(); 19 | 20 | eslintTester.run("detect-angular-trustAsJs-method", rule, { 21 | valid: [ 22 | { code: "$sce.trustAsJs('stringLiteral');" }, // string literals are OK 23 | { code: "$sce.ParseAsHtml()" }, 24 | { code: "this.$sce.ParseAsHtml()" } // no need to look for valid as we are just doing detection 25 | ], 26 | invalid: [ 27 | { 28 | code: "$sce.trustAsJs(value);", 29 | errors: [ 30 | { message: "The use of $sce.trustAsJs can be dangerous" } 31 | ], 32 | }, 33 | { 34 | code: "this.$sce.trustAsJs(value);", 35 | errors: [ 36 | { message: "The use of $sce.trustAsJs can be dangerous" } 37 | ], 38 | } 39 | ] 40 | }); 41 | -------------------------------------------------------------------------------- /tests/rules/detect-angular-trustAsResouceUrl-method.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview Test for detect-angular-trustAs-methods 3 | * @author Lewis Ardern 4 | */ 5 | "use strict"; 6 | 7 | //------------------------------------------------------------------------------ 8 | // Requirements 9 | //------------------------------------------------------------------------------ 10 | 11 | var rule = require("../../lib/rules/detect-angular-trustAsResourceUrl-method"); 12 | var RuleTester = require('eslint').RuleTester; 13 | 14 | //------------------------------------------------------------------------------ 15 | // Tests 16 | //------------------------------------------------------------------------------ 17 | 18 | var eslintTester = new RuleTester(); 19 | 20 | eslintTester.run("detect-angular-trustAsResourceUrl-method", rule, { 21 | valid: [ 22 | { code: "$sce.trustAsResourceUrl('stringLiteral');" }, // string literals are OK 23 | { code: "$sce.ParseAsHtml()" }, 24 | { code: "this.$sce.ParseAsHtml()" } // no need to look for valid as we are just doing detection 25 | ], 26 | invalid: [ 27 | { 28 | code: "$sce.trustAsResourceUrl(value);", 29 | errors: [ 30 | { message: "The use of $sce.trustAsResourceUrl can be dangerous" } 31 | ], 32 | }, 33 | { 34 | code: "this.$sce.trustAsResourceUrl(value);", 35 | errors: [ 36 | { message: "The use of $sce.trustAsResourceUrl can be dangerous" } 37 | ], 38 | } 39 | ] 40 | }); 41 | -------------------------------------------------------------------------------- /tests/rules/detect-third-party-angular-translate.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview Test for detect-third-party-angular-translate 3 | * @author Lewis Ardern 4 | */ 5 | "use strict"; 6 | 7 | //------------------------------------------------------------------------------ 8 | // Requirements 9 | //------------------------------------------------------------------------------ 10 | 11 | var rule = require("../../lib/rules/detect-third-party-angular-translate"); 12 | var RuleTester = require('eslint').RuleTester; 13 | 14 | //------------------------------------------------------------------------------ 15 | // Tests 16 | //------------------------------------------------------------------------------ 17 | 18 | var eslintTester = new RuleTester(); 19 | 20 | eslintTester.run("detect-third-party-angular-translate", rule, { 21 | valid: [ 22 | { code: "foo()" } // no need to look for valid as we are just doing detection 23 | ], 24 | invalid: [ 25 | { 26 | code: "$translateSanitization.useStrategy();", 27 | errors: [ 28 | { message: "If the $translateSanitization.useStrategy is set to null or blank this can be dangerous" } 29 | ], 30 | }, 31 | { 32 | code: "$translateProvider.translations('de', {GREETING: 'Hallo {{name}}'});", 33 | errors: [ 34 | { message: "The use of $translateProvider can be dangerous" } 35 | ], 36 | } 37 | ] 38 | }); 39 | --------------------------------------------------------------------------------