From c559172c2866f9b2c4463c86a05f16bd8bd485aa Mon Sep 17 00:00:00 2001 From: Danny Grander Date: Thu, 23 Jun 2016 12:52:25 -0700 Subject: [PATCH 1/5] feat: switch from git to npm version of recursive-readdir --- lib/protect/patch.js | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/protect/patch.js b/lib/protect/patch.js index 4ef943a9b2a..8e02400006e 100644 --- a/lib/protect/patch.js +++ b/lib/protect/patch.js @@ -5,7 +5,7 @@ var now = new Date(); var debug = require('debug')('snyk'); var Promise = require('es6-promise').Promise; // jshint ignore:line var chalk = require('chalk'); -var recursive = require('recursive-readdir'); +var recursive = require('snyk-recursive-readdir'); var request = require('request'); var tempfile = require('tempfile'); var fs = require('then-fs'); diff --git a/package.json b/package.json index 5215462b0c1..0804d6f6875 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "node-uuid": "^1.4.3", "open": "^0.0.5", "os-name": "^1.0.3", - "recursive-readdir": "https://github.com/Snyk/recursive-readdir", + "snyk-recursive-readdir": "^2.0.0", "request": "^2.60.0", "semver": "^5.1.0", "snyk-config": "1.0.1", From 7e954bc99dcf95831301e7a555f6c5fe8116c5c1 Mon Sep 17 00:00:00 2001 From: Clay Miller Date: Tue, 21 Jun 2016 23:59:22 -0700 Subject: [PATCH 2/5] fix: patch filename compat with windows Fixes #22 TL,DR; use dash instead of colons. --- lib/protect/write-patch-flag.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/protect/write-patch-flag.js b/lib/protect/write-patch-flag.js index a9ff66f62dc..60cc39d35e3 100644 --- a/lib/protect/write-patch-flag.js +++ b/lib/protect/write-patch-flag.js @@ -13,13 +13,16 @@ function writePatchFlag(now, vuln) { debug('writing flag for %s', vuln.id); var promise; - var flag = path.resolve(vuln.source, '.snyk-' + vuln.id + '.flag'); + // the colon doesn't like Windows, ref: https://git.io/vw2iO + var fileSafeId = vuln.id.replace(/:/g, '-'); + var flag = path.resolve(vuln.source, '.snyk-' + fileSafeId + '.flag'); if (vuln.grouped && vuln.grouped.includes) { debug('found addition vulns to write flag files for'); var writePromises = [fs.writeFile(flag, now.toJSON(), 'utf8')]; debug(flag); vuln.grouped.includes.forEach(function (id) { - var flag = path.resolve(vuln.source, '.snyk-' + id + '.flag'); + var fileSafeId = vuln.id.replace(/:/g, '-'); + var flag = path.resolve(vuln.source, '.snyk-' + fileSafeId + '.flag'); debug(flag); writePromises.push(fs.writeFile(flag, now.toJSON(), 'utf8')); }); @@ -31,4 +34,4 @@ function writePatchFlag(now, vuln) { return promise.then(function () { return vuln; }); -} \ No newline at end of file +} From e4bc4b0a6d0f062d944b578ae50aa965e56a6a2a Mon Sep 17 00:00:00 2001 From: Assaf Date: Wed, 29 Jun 2016 16:24:50 +0300 Subject: [PATCH 3/5] docs: update readme file add snyk badge (#112) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 2b61ed664c8..ad90c39bc4e 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ +[![Known Vulnerabilities](https://snyk.io/test/npm/snyk/badge.svg)](https://snyk.io/test/npm/snyk) # Documentation Snyk helps you find, fix and monitor for known vulnerabilities in Node.js npm packages, both ad hoc and as part of your CI (Build) system. From bad04d7775c224429110c4f9605fb1cda311643a Mon Sep 17 00:00:00 2001 From: Remy Sharp Date: Tue, 5 Jul 2016 15:28:47 +0100 Subject: [PATCH 4/5] WIP: capture the parent dep type --- lib/protect/update.js | 9 +++++++++ lib/test.js | 6 ++++++ 2 files changed, 15 insertions(+) diff --git a/lib/protect/update.js b/lib/protect/update.js index 04c5ace800e..a4dd801332b 100644 --- a/lib/protect/update.js +++ b/lib/protect/update.js @@ -16,10 +16,17 @@ function update(packages, live) { // the uninstall doesn't need versions in the strings // but install *does* so we build up arrays of both var upgradeWithoutVersions = []; + var upgrade = packages.map(function (vuln) { // FIXME the line below is wrong, should be .filter(Boolean)[0] var remediation = vuln.upgradePath.filter(Boolean)[0]; upgradeWithoutVersions.push(remediation.split('@').shift()); + + // TODO fix this string + if (vuln.parentDep === 'dev') { + console.log('>>>>>>>>>>>>>>>>'); + } + return remediation; }); @@ -31,6 +38,8 @@ function update(packages, live) { var toUninstall = _.unique(upgradeWithoutVersions); var promise = npm('uninstall', toUninstall, live).then(function () { + // FIXME this only adds to prod deps + // it should respect the dep type here return npm('install', findUpgrades(upgrade), live).catch(function (e) { error = e; return false; diff --git a/lib/test.js b/lib/test.js index 55f3edc6515..11866e1acd1 100644 --- a/lib/test.js +++ b/lib/test.js @@ -121,6 +121,12 @@ function test(root, options, callback) { vuln.__filename = plucked.__filename; vuln.shrinkwrap = plucked.shrinkwrap; vuln.bundled = plucked.bundled; + + vuln.depType = plucked.depType; + + var parentPkg = moduleToOjbect(vuln.from[1]); + var parent = modules.pluck(vuln.from.slice(0, 2), parentPkg.name, parentPkg.version); + vuln.parentDep = parent.depType; }); } } From 2aa8feab0e7d13a334540485852448306b06b109 Mon Sep 17 00:00:00 2001 From: Alon Niv Date: Tue, 5 Jul 2016 18:41:49 +0300 Subject: [PATCH 5/5] fix: make sure dev deps are saved propery --- cli/commands/protect/wizard.js | 2 +- lib/npm.js | 9 +- lib/protect/update.js | 32 +- lib/test.js | 8 +- test/fixtures/SC-1472.json | 401 +++++++++++++++++++++++++ test/fixtures/pkg-SC-1472/package.json | 19 ++ test/wizard-process-answers.test.js | 25 +- 7 files changed, 474 insertions(+), 22 deletions(-) create mode 100644 test/fixtures/SC-1472.json create mode 100644 test/fixtures/pkg-SC-1472/package.json diff --git a/cli/commands/protect/wizard.js b/cli/commands/protect/wizard.js index 86e5f3f95f5..f4b6eb1e437 100644 --- a/cli/commands/protect/wizard.js +++ b/cli/commands/protect/wizard.js @@ -343,7 +343,7 @@ function processAnswers(answers, policy, options) { var lbl = 'Updating npm-shrinkwrap.json...'; return spinner(lbl) - .then(npm.bind(null, 'shrinkwrap', null, live, cwd)) + .then(npm.bind(null, 'shrinkwrap', null, live, cwd, null)) .then(spinner.clear(lbl)); } }) diff --git a/lib/npm.js b/lib/npm.js index 6364f164faa..fb4fa3d6535 100644 --- a/lib/npm.js +++ b/lib/npm.js @@ -3,7 +3,8 @@ module.exports = npm; var debug = require('debug')('snyk'); var exec = require('child_process').exec; -function npm(method, packages, live, cwd) { +function npm(method, packages, live, cwd, flags) { + flags = flags || []; if (!packages) { packages = []; } @@ -14,10 +15,12 @@ function npm(method, packages, live, cwd) { // only if we have packages, then always save, otherwise the command might // be something like `npm shrinkwrap' - if (packages.length) { - method = '--save ' + method; + if (packages.length && !flags.length) { + flags.push('--save'); } + method += ' ' + flags.join(' '); + return new Promise(function (resolve, reject) { var cmd = 'npm ' + method + ' ' + packages.join(' '); if (!cwd) { diff --git a/lib/protect/update.js b/lib/protect/update.js index a4dd801332b..3c6f0b0266a 100644 --- a/lib/protect/update.js +++ b/lib/protect/update.js @@ -12,6 +12,7 @@ var spinner = require('../spinner'); function update(packages, live) { var lbl = 'Running `npm update`...'; var error = false; + return spinner(lbl).then(function () { // the uninstall doesn't need versions in the strings // but install *does* so we build up arrays of both @@ -22,13 +23,17 @@ function update(packages, live) { var remediation = vuln.upgradePath.filter(Boolean)[0]; upgradeWithoutVersions.push(remediation.split('@').shift()); - // TODO fix this string - if (vuln.parentDep === 'dev') { - console.log('>>>>>>>>>>>>>>>>'); + return { + remediation: remediation, + type: vuln.parentDepType || 'prod', + }; + }).reduce(function (ups, vuln) { + if (!ups[vuln.type]) { + ups[vuln.type] = []; } - - return remediation; - }); + ups[vuln.type].push(vuln.remediation); + return ups; + }, {}); debug('to upgrade', upgrade); @@ -38,12 +43,21 @@ function update(packages, live) { var toUninstall = _.unique(upgradeWithoutVersions); var promise = npm('uninstall', toUninstall, live).then(function () { - // FIXME this only adds to prod deps - // it should respect the dep type here - return npm('install', findUpgrades(upgrade), live).catch(function (e) { + var prodUpdate = (upgrade.prod ? + npm('install', findUpgrades(upgrade.prod), live) : + Promise.resolve(true)).catch(function (e) { error = e; return false; }); + var devUpdate = (upgrade.dev ? + npm('install', findUpgrades(upgrade.dev), live, null, ['--save-dev']) : + Promise.resolve(true)).catch(function (e) { + error = e; + return false; + }); + return Promise.all([prodUpdate, devUpdate]).then(function (results) { + return results[0] && results[1]; + }); }); return promise; diff --git a/lib/test.js b/lib/test.js index 11866e1acd1..70d471a0ad4 100644 --- a/lib/test.js +++ b/lib/test.js @@ -122,11 +122,11 @@ function test(root, options, callback) { vuln.shrinkwrap = plucked.shrinkwrap; vuln.bundled = plucked.bundled; - vuln.depType = plucked.depType; - var parentPkg = moduleToOjbect(vuln.from[1]); - var parent = modules.pluck(vuln.from.slice(0, 2), parentPkg.name, parentPkg.version); - vuln.parentDep = parent.depType; + var parent = modules.pluck(vuln.from.slice(0, 2), + parentPkg.name, + parentPkg.version); + vuln.parentDepType = parent.depType; }); } } diff --git a/test/fixtures/SC-1472.json b/test/fixtures/SC-1472.json new file mode 100644 index 00000000000..954f7a57817 --- /dev/null +++ b/test/fixtures/SC-1472.json @@ -0,0 +1,401 @@ +{ + "npm:minimatch:20160620-u0": { + "vuln": { + "title": "Regular Expression Denial of Service", + "creationTime": "2016-06-20T16:00:06.484Z", + "modificationTime": "2016-06-20T16:00:06.484Z", + "publicationTime": "2016-06-20T15:52:52.000Z", + "disclosureTime": "2016-06-20T15:52:52.000Z", + "semver": { + "vulnerable": "<=3.0.1", + "unaffected": ">=3.0.2" + }, + "CVSSv3": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", + "severity": "high", + "identifiers": { + "CWE": [ + "CWE-400" + ], + "CVE": [], + "NSP": 118 + }, + "patches": [ + { + "urls": [ + "https://raw.githubusercontent.com/Snyk/vulndb/snapshots/master/patches/npm/minimatch/20160620/minimatch_20160620_0_0_6944abf9e0694bd22fd9dad293faa40c2bc8a955.patch" + ], + "version": "<=3.0.1 >2.0.5", + "modificationTime": "2016-06-20T16:00:06.484Z", + "comments": [], + "id": "patch:npm:minimatch:20160620:0" + } + ], + "moduleName": "minimatch", + "id": "npm:minimatch:20160620", + "from": [ + "SC-1472@1.0.0", + "minimatch@3.0.0" + ], + "upgradePath": [ + false, + "minimatch@3.0.2" + ], + "version": "3.0.0", + "name": "minimatch", + "isUpgradable": true, + "isPatchable": true, + "__filename": "/Users/oakfang/dev/SC-1472/node_modules/minimatch/package.json", + "parentDepType": "prod" + }, + "choice": "update" + }, + "npm:qs:20140806-u1": { + "vuln": { + "title": "Denial of Service (Memory Exhaustion)", + "semver": { + "vulnerable": "<1.0.0", + "unaffected": ">= 1.x" + }, + "CVSSv2": "5.0 (MEDIUM) (AV:N/AC:L/Au:N/C:N/I:N/A:P)", + "CVSSv3": "", + "severity": "medium", + "identifiers": { + "CWE": [ + "CWE-400" + ], + "CVE": [ + "CVE-2014-7191" + ], + "NSP": 29 + }, + "patches": [ + { + "urls": [ + "https://raw.githubusercontent.com/Snyk/vulndb/snapshots/master/patches/npm/qs/20140806/qs_20140806_0_0_43a604b7847e56bba49d0ce3e222fe89569354d8_snyk.patch" + ], + "version": "<1.0.0 >=0.6.5", + "modificationTime": "2014-08-06T06:10:22.000Z", + "comments": [], + "id": "patch:npm:qs:20140806:0" + } + ], + "moduleName": "qs", + "creationTime": "2014-08-06T06:10:22.000Z", + "publicationTime": "2014-08-06T06:10:22.000Z", + "modificationTime": "2015-11-06T02:09:36.180Z", + "disclosureTime": "2014-08-06T06:10:22.000Z", + "id": "npm:qs:20140806", + "from": [ + "SC-1472@1.0.0", + "qs@0.6.6" + ], + "upgradePath": [ + false, + "qs@1.0.0" + ], + "version": "0.6.6", + "name": "qs", + "isUpgradable": true, + "isPatchable": true, + "__filename": "/Users/oakfang/dev/SC-1472/node_modules/qs/package.json", + "parentDepType": "dev", + "grouped": { + "affected": { + "name": "qs", + "version": "0.6.6", + "full": "qs@0.6.6" + }, + "main": true, + "id": "npm:qs:20140806-2", + "count": 2, + "upgrades": [] + } + }, + "choice": "update" + }, + "npm:minimatch:20160620-u4": { + "vuln": { + "title": "Regular Expression Denial of Service", + "creationTime": "2016-06-20T16:00:06.484Z", + "modificationTime": "2016-06-20T16:00:06.484Z", + "publicationTime": "2016-06-20T15:52:52.000Z", + "disclosureTime": "2016-06-20T15:52:52.000Z", + "semver": { + "vulnerable": "<=3.0.1", + "unaffected": ">=3.0.2" + }, + "CVSSv3": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", + "severity": "high", + "identifiers": { + "CWE": [ + "CWE-400" + ], + "CVE": [], + "NSP": 118 + }, + "patches": [ + { + "urls": [ + "https://raw.githubusercontent.com/Snyk/vulndb/snapshots/master/patches/npm/minimatch/20160620/minimatch_20160620_0_0_6944abf9e0694bd22fd9dad293faa40c2bc8a955.patch" + ], + "version": "<=3.0.1 >2.0.5", + "modificationTime": "2016-06-20T16:00:06.484Z", + "comments": [], + "id": "patch:npm:minimatch:20160620:0" + } + ], + "moduleName": "minimatch", + "id": "npm:minimatch:20160620", + "from": [ + "SC-1472@1.0.0", + "tap@3.1.2", + "glob@6.0.4", + "minimatch@3.0.0" + ], + "upgradePath": [ + false, + "tap@3.1.2", + "glob@6.0.4", + "minimatch@3.0.2" + ], + "version": "3.0.0", + "name": "minimatch", + "isUpgradable": true, + "isPatchable": true, + "__filename": "/Users/oakfang/dev/SC-1472/node_modules/minimatch/package.json", + "parentDepType": "dev", + "grouped": { + "affected": { + "name": "tap", + "version": "3.1.2", + "full": "tap@3.1.2" + }, + "main": true, + "id": "npm:minimatch:20160620-4", + "count": 3, + "upgrades": [ + "minimatch@3.0.2" + ] + } + }, + "choice": "update" + }, + "npm:minimatch:20160620-p0": { + "vuln": { + "title": "Regular Expression Denial of Service", + "creationTime": "2016-06-20T16:00:06.484Z", + "modificationTime": "2016-06-20T16:00:06.484Z", + "publicationTime": "2016-06-20T15:52:52.000Z", + "disclosureTime": "2016-06-20T15:52:52.000Z", + "semver": { + "vulnerable": "<=3.0.1", + "unaffected": ">=3.0.2" + }, + "CVSSv3": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", + "severity": "high", + "identifiers": { + "CWE": [ + "CWE-400" + ], + "CVE": [], + "NSP": 118 + }, + "patches": [ + { + "urls": [ + "https://raw.githubusercontent.com/Snyk/vulndb/snapshots/master/patches/npm/minimatch/20160620/minimatch_20160620_0_0_6944abf9e0694bd22fd9dad293faa40c2bc8a955.patch" + ], + "version": "<=3.0.1 >2.0.5", + "modificationTime": "2016-06-20T16:00:06.484Z", + "comments": [], + "id": "patch:npm:minimatch:20160620:0" + } + ], + "moduleName": "minimatch", + "id": "npm:minimatch:20160620", + "from": [ + "SC-1472@1.0.0", + "tap@3.1.2", + "nyc@5.6.0", + "istanbul@0.4.4", + "fileset@0.2.1", + "minimatch@2.0.10" + ], + "upgradePath": [ + false, + false, + false, + false, + "fileset@1.0.1", + "minimatch@3.0.2" + ], + "version": "2.0.10", + "name": "minimatch", + "isUpgradable": false, + "isPatchable": true, + "__filename": "/Users/oakfang/dev/SC-1472/node_modules/fileset/node_modules/minimatch/package.json", + "parentDepType": "dev" + }, + "choice": "patch" + }, + "npm:request:20160119-p1": { + "vuln": { + "title": "Remote Memory Exposure", + "creationTime": "2016-03-22T12:00:05.158Z", + "modificationTime": "2016-03-22T12:00:05.158Z", + "publicationTime": "2016-03-22T12:00:05.158Z", + "semver": { + "vulnerable": "<2.68.0 >2.2.5", + "unaffected": ">=2.68.0 <=2.2.6" + }, + "CVSSv3": "", + "severity": "medium", + "identifiers": { + "CWE": [ + "CWE-201" + ], + "CVE": [] + }, + "patches": [ + { + "urls": [ + "https://raw.githubusercontent.com/Snyk/vulndb/snapshots/master/patches/npm/request/20160119/request_20160119_0_0_3d31d4526fa4d4e4f59b89cabe194fb671063cdb.patch" + ], + "version": "<2.68.0 >=2.54.0", + "modificationTime": "2016-03-22T12:00:05.158Z", + "comments": [], + "id": "patch:npm:request:20160119:0" + } + ], + "moduleName": "request", + "disclosureTime": "2016-01-19T04:57:05.158Z", + "id": "npm:request:20160119", + "from": [ + "SC-1472@1.0.0", + "tap@3.1.2", + "coveralls@2.11.9", + "request@2.67.0" + ], + "upgradePath": [ + false, + false, + false, + "request@2.68.0" + ], + "version": "2.67.0", + "name": "request", + "isUpgradable": false, + "isPatchable": true, + "__filename": "/Users/oakfang/dev/SC-1472/node_modules/coveralls/node_modules/request/package.json", + "parentDepType": "dev", + "grouped": { + "affected": { + "name": "request", + "version": "2.67.0", + "full": "request" + }, + "main": true, + "id": "npm:request:20160119-3", + "count": 2, + "upgrades": [ + { + "from": [ + "SC-1472@1.0.0", + "tap@3.1.2", + "coveralls@2.11.9", + "request@2.67.0" + ], + "filename": "/Users/oakfang/dev/SC-1472/node_modules/coveralls/node_modules/request/package.json", + "patches": [ + { + "urls": [ + "https://raw.githubusercontent.com/Snyk/vulndb/snapshots/master/patches/npm/request/20160119/request_20160119_0_0_3d31d4526fa4d4e4f59b89cabe194fb671063cdb.patch" + ], + "version": "<2.68.0 >=2.54.0", + "modificationTime": "2016-03-22T12:00:05.158Z", + "comments": [], + "id": "patch:npm:request:20160119:0" + } + ], + "version": "2.67.0" + }, + { + "from": [ + "SC-1472@1.0.0", + "tap@3.1.2", + "codecov.io@0.1.6", + "request@2.42.0" + ], + "filename": "/Users/oakfang/dev/SC-1472/node_modules/request/package.json", + "patches": [ + { + "urls": [ + "https://raw.githubusercontent.com/Snyk/vulndb/snapshots/master/patches/npm/request/20160119/request_20160119_0_4_3d31d4526fa4d4e4f59b89cabe194fb671063cdb.patch" + ], + "version": "<2.47.0 >=2.27.0", + "modificationTime": "2016-03-27T12:00:05.158Z", + "comments": [], + "id": "patch:npm:request:20160119:4" + } + ], + "version": "2.42.0" + } + ], + "patch": true + } + }, + "choice": "patch" + }, + "npm:hawk:20160119-i0": { + "meta": { + "days": 30 + }, + "vuln": { + "title": "Regular Expression Denial of Service", + "creationTime": "2016-01-19T23:24:51.834Z", + "modificationTime": "2016-01-19T23:24:51.834Z", + "publicationTime": "2016-01-19T23:24:51.834Z", + "semver": { + "vulnerable": "<=3.1.2 || >= 4.0.0 <4.1.1", + "unaffected": ">3.1.2 < 4.0.0 || >=4.1.1" + }, + "CVSSv3": "", + "severity": "low", + "identifiers": { + "CWE": [ + "CWE-400" + ], + "CVE": [], + "NSP": 77 + }, + "patches": [], + "moduleName": "hawk", + "disclosureTime": "2016-01-19T21:51:35.396Z", + "id": "npm:hawk:20160119", + "from": [ + "SC-1472@1.0.0", + "tap@3.1.2", + "codecov.io@0.1.6", + "request@2.42.0", + "hawk@1.1.1" + ], + "upgradePath": [ + false, + false, + false, + "request@2.59.0", + "hawk@3.1.3" + ], + "version": "1.1.1", + "name": "hawk", + "isUpgradable": false, + "isPatchable": false, + "__filename": "/Users/oakfang/dev/SC-1472/node_modules/hawk/package.json", + "parentDepType": "dev" + }, + "choice": "ignore" + }, + "npm:hawk:20160119-i0-reason": "None given", + "misc-add-test": false, + "misc-add-protect": false +} \ No newline at end of file diff --git a/test/fixtures/pkg-SC-1472/package.json b/test/fixtures/pkg-SC-1472/package.json new file mode 100644 index 00000000000..72e1800ea9e --- /dev/null +++ b/test/fixtures/pkg-SC-1472/package.json @@ -0,0 +1,19 @@ +{ + "name": "SC-1472", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "devDependencies": { + "qs": "0.6.6", + "tap": "3.1.2" + }, + "dependencies": { + "minimatch": "3.0.0" + } +} \ No newline at end of file diff --git a/test/wizard-process-answers.test.js b/test/wizard-process-answers.test.js index 907a6779e8a..8f85958d8b9 100644 --- a/test/wizard-process-answers.test.js +++ b/test/wizard-process-answers.test.js @@ -44,7 +44,7 @@ snyk.policy.save = function (data) { var wizard = proxyquire('../cli/commands/protect/wizard', { '../../../lib/npm': function (cmd) { execSpy(cmd); - return Promise.resolve(); + return Promise.resolve(true); }, 'then-fs': thenfs, '../../../lib/protect': proxyquire('../lib/protect', { @@ -69,8 +69,9 @@ var wizard = proxyquire('../cli/commands/protect/wizard', { }) }), './update': proxyquire('../lib/protect/update', { - '../npm': function () { - return Promise.resolve(); + '../npm': function (cmd, packages, live, cwd, flags) { + execSpy(cmd, packages, live, cwd, flags); + return Promise.resolve(true); }, }), }), @@ -112,8 +113,8 @@ test('process answers handles shrinkwrap', function (t) { process.chdir(__dirname + '/fixtures/pkg-mean-io/'); var answers = require(__dirname + '/fixtures/mean-answers.json'); answers['misc-test-no-monitor'] = true; - wizard.processAnswers(answers).then(function () { - var shrinkCall = execSpy.getCall(0); // get the 2nd call (as the first is the install of snyk) + wizard.processAnswers(answers, mockPolicy).then(function () { + var shrinkCall = execSpy.getCall(2); // get the 2nd call (as the first is the install of snyk) t.equal(shrinkCall.args[0], 'shrinkwrap', 'shrinkwrap was called'); process.chdir(cwd); }).catch(t.threw).then(t.end); @@ -121,6 +122,20 @@ test('process answers handles shrinkwrap', function (t) { }); }); +test('wizard updates vulns without changing dep type', function (t) { + execSpy = sinon.spy(); + var cwd = process.cwd(); + process.chdir(__dirname + '/fixtures/pkg-SC-1472/'); + var answers = require(__dirname + '/fixtures/SC-1472.json'); + answers['misc-test-no-monitor'] = true; + wizard.processAnswers(answers, mockPolicy).then(function () { + t.equal(execSpy.callCount, 3, 'uninstall, install prod, install dev'); + t.equal(execSpy.getCall(1).args[1].length, 1, '1 prod dep'); + t.equal(execSpy.getCall(1).args[1].length, 1, '2 dev dep'); + process.chdir(cwd); + }).catch(t.threw).then(t.end); +}); + test('wizard replaces npm\s default scripts.test', function (t) { var old = process.cwd(); var dir = path.resolve(__dirname, 'fixtures', 'no-deps');