From c88c666cb9227135f72f8c4ea32cb28b86d7f516 Mon Sep 17 00:00:00 2001 From: claudiahdz Date: Fri, 9 Aug 2019 16:42:45 -0500 Subject: [PATCH 1/3] feat: throw forbidden error when package is blocked by security policy --- index.js | 33 ++++++++++++++++++++++----------- test/index.js | 29 +++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 11 deletions(-) diff --git a/index.js b/index.js index d9a8373..331a299 100644 --- a/index.js +++ b/index.js @@ -23,6 +23,9 @@ function pickManifest (packument, wanted, opts) { const versions = Object.keys(packument.versions || {}).filter(v => { return semver.valid(v, true) }) + const policyRestrictions = packument.policyRestrictions + const restrictedVersions = policyRestrictions + ? Object.keys(packument.policyRestrictions.restrictedVersions) : [] function enjoyableBy (v) { return !time || ( @@ -32,7 +35,7 @@ function pickManifest (packument, wanted, opts) { let err - if (!versions.length) { + if (!versions.length && !restrictedVersions.length) { err = new Error(`No valid versions available for ${packument.name}`) err.code = 'ENOVERSIONS' err.name = packument.name @@ -98,16 +101,24 @@ function pickManifest (packument, wanted, opts) { packument.versions[target] ) if (!manifest) { - err = new Error( - `No matching version found for ${packument.name}@${wanted}${ - opts.enjoyBy - ? ` with an Enjoy By date of ${ - new Date(opts.enjoyBy).toLocaleString() - }. Maybe try a different date?` - : '' - }` - ) - err.code = 'ETARGET' + // Check if target is forbidden + const isForbidden = target && policyRestrictions && packument.policyRestrictions.restrictedVersions[target] + const pckg = `${packument.name}@${wanted}${ + opts.enjoyBy + ? ` with an Enjoy By date of ${ + new Date(opts.enjoyBy).toLocaleString() + }. Maybe try a different date?` + : '' + }` + + if (isForbidden) { + err = new Error(`Could not download ${pckg} due to policy violations.\n${packument.policyRestrictions.message}\n`) + err.code = 'E403' + } else { + err = new Error(`No matching version found for ${pckg}.`) + err.code = 'ETARGET' + } + err.name = packument.name err.type = type err.wanted = wanted diff --git a/test/index.js b/test/index.js index c583aec..9bd14b2 100644 --- a/test/index.js +++ b/test/index.js @@ -128,6 +128,25 @@ test('ETARGET if range does not match anything', t => { t.done() }) +test('E403 if version is forbidden', t => { + const metadata = { + policyRestrictions: { + restrictedVersions: { + '2.1.0': { version: '2.1.0' } + } + }, + versions: { + '1.0.0': { version: '1.0.0' }, + '2.0.0': { version: '2.0.0' }, + '2.0.5': { version: '2.0.5' } + } + } + t.throws(() => { + pickManifest(metadata, '2.1.0') + }, {code: 'E403'}, 'got correct error on match failure') + t.done() +}) + test('if `defaultTag` matches a given range, use it', t => { const metadata = { 'dist-tags': { @@ -195,6 +214,16 @@ test('errors if metadata has no versions', t => { t.done() }) +test('errors if metadata has no versions or restricted versions', t => { + t.throws(() => { + pickManifest({versions: {}, policyRestrictions: { restrictedVersions: {} }}, '^1.0.0') + }, {code: 'ENOVERSIONS'}) + t.throws(() => { + pickManifest({}, '^1.0.0') + }, {code: 'ENOVERSIONS'}) + t.done() +}) + test('matches even if requested version has spaces', t => { const metadata = { versions: { From c1fc20e2345566a97e901a83f6c150c42ad8dbca Mon Sep 17 00:00:00 2001 From: claudiahdz Date: Mon, 12 Aug 2019 13:19:34 -0500 Subject: [PATCH 2/3] chore: remove node 4.0 from travis --- .travis.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index f77cd9a..4ad5b87 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,5 +2,4 @@ language: node_js sudo: false node_js: - "7" - - "6" - - "4" + - "6" \ No newline at end of file From 45b6df33ff5a43eaf680c647bc6ccdc81cdb2fca Mon Sep 17 00:00:00 2001 From: claudiahdz Date: Mon, 19 Aug 2019 16:32:52 -0500 Subject: [PATCH 3/3] chore: update policyRestrictions object structure --- index.js | 6 +++--- test/index.js | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/index.js b/index.js index 331a299..b9a82ec 100644 --- a/index.js +++ b/index.js @@ -25,7 +25,7 @@ function pickManifest (packument, wanted, opts) { }) const policyRestrictions = packument.policyRestrictions const restrictedVersions = policyRestrictions - ? Object.keys(packument.policyRestrictions.restrictedVersions) : [] + ? Object.keys(policyRestrictions.versions) : [] function enjoyableBy (v) { return !time || ( @@ -102,7 +102,7 @@ function pickManifest (packument, wanted, opts) { ) if (!manifest) { // Check if target is forbidden - const isForbidden = target && policyRestrictions && packument.policyRestrictions.restrictedVersions[target] + const isForbidden = target && policyRestrictions && policyRestrictions.versions[target] const pckg = `${packument.name}@${wanted}${ opts.enjoyBy ? ` with an Enjoy By date of ${ @@ -112,7 +112,7 @@ function pickManifest (packument, wanted, opts) { }` if (isForbidden) { - err = new Error(`Could not download ${pckg} due to policy violations.\n${packument.policyRestrictions.message}\n`) + err = new Error(`Could not download ${pckg} due to policy violations.\n${policyRestrictions.message}\n`) err.code = 'E403' } else { err = new Error(`No matching version found for ${pckg}.`) diff --git a/test/index.js b/test/index.js index 9bd14b2..d826d33 100644 --- a/test/index.js +++ b/test/index.js @@ -131,7 +131,7 @@ test('ETARGET if range does not match anything', t => { test('E403 if version is forbidden', t => { const metadata = { policyRestrictions: { - restrictedVersions: { + versions: { '2.1.0': { version: '2.1.0' } } }, @@ -216,7 +216,7 @@ test('errors if metadata has no versions', t => { test('errors if metadata has no versions or restricted versions', t => { t.throws(() => { - pickManifest({versions: {}, policyRestrictions: { restrictedVersions: {} }}, '^1.0.0') + pickManifest({versions: {}, policyRestrictions: { versions: {} }}, '^1.0.0') }, {code: 'ENOVERSIONS'}) t.throws(() => { pickManifest({}, '^1.0.0')