Skip to content
This repository has been archived by the owner on Sep 11, 2023. It is now read-only.

Commit

Permalink
feat: Migrate from legacy /vuln endpoint to /test
Browse files Browse the repository at this point in the history
This PR migrates the vulncost plugin to use the `/test` endpoint instead
of `/vuln`, which is being removed soon. Since `/test` does not support
resolving `latest` as a version (which is an NPM specific concept), we
shift the version resolution to the plugin
  • Loading branch information
robcresswell committed Apr 19, 2021
1 parent 8ceaca8 commit 1170fd7
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 33 deletions.
26 changes: 17 additions & 9 deletions src/getImports/packageInfo.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ import logger from '../logger';

import { DebounceError, debouncePromise } from './debouncePromise';
import report from '../report';
import axios from 'axios';

let cache = {};
let vulnCache = {};
const projectCache = {};

export function getPackageKey(pkg) {
export async function getPackageKey(pkg) {
if (pkg.version && pkg.name) {
return { name: pkg.name, version: pkg.version };
}
Expand All @@ -29,13 +30,20 @@ export function getPackageKey(pkg) {
let packageInfo = f.next().value;

// if the package doesn't start with the package name we were looking for
// then it means it's not locally installed, so let's assume they're going
// to install and set version to "latest"
// then it means it's not locally installed, so let's get the version from the
// npm registry
if (!packageInfo.name || !packageInfo.name.toLowerCase().startsWith(name)) {
packageInfo = {
name,
version: 'latest',
};
try {
const res = await axios.get(`https://registry.npmjs.org/${name}`);
const version = res.data['dist-tags']['latest'];

return { name, version };
} catch (err) {
return {
name,
version: 'latest',
};
}
}

return { name: packageInfo.name, version: packageInfo.version };
Expand All @@ -57,9 +65,9 @@ export function getPackageFromCache(key) {
export async function getPackageInfo(pkg) {
try {
if (pkg.string) {
cache[pkg.string] = cache[pkg.string] || getPackageKey(pkg);
cache[pkg.string] = cache[pkg.string] || (await getPackageKey(pkg));
} else {
cache[pkg.string] = getPackageKey(pkg);
cache[pkg.string] = await getPackageKey(pkg);
}
} catch (e) {
logger.log(e.message);
Expand Down
38 changes: 14 additions & 24 deletions src/getImports/testVuln.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
import { isAuthed, getToken } from './snykAPI';
import axios from 'axios';
import logger from '../logger';
import utm from '../utm';
import statistics from '../statistics';

const API_ROOT = 'https://snyk.io/api/v1/vuln/npm/';
import utm from '../utm';
import { getToken, isAuthed } from './snykAPI';

function testNoAuth(key) {
return axios
.get(`https://snyk.io/test/npm/${key}?${utm}&type=json`)
.then(({ data }) => {
if (typeof data === 'string') {
// bug on snyk's side, returning a string for 404
logger.log('bad return on ' + key);
logger.log(`bad return on ${key}`);
throw new Error('bad return from snyk api (unauthed)');
}

Expand All @@ -24,36 +22,28 @@ function testNoAuth(key) {
});
}

function testWithAuth(pkg) {
const encodedName = encodeURIComponent(pkg.name + '@' + pkg.version);
// options.vulnEndpoint is only used by `snyk protect` (i.e. local filesystem tests)
const url = API_ROOT + encodedName + '?' + utm;
function testWithAuth({ name, version }) {
const encodedName = encodeURIComponent(name);
const url = `https://snyk.io/api/v1/test/npm/${encodedName}/${version}?${utm}`;

return axios
.get(url, {
headers: {
'x-is-ci': false,
authorization: 'token ' + getToken(),
authorization: `token ${getToken()}`,
},
})
.then(res => {
const packageName = decodeURIComponent(
res.request.res.responseUrl.replace(API_ROOT, '')
).replace(/\?.*$/, '');

const vulns = res.data.vulnerabilities || [];

const vulnerabilities = res.data.issues.vulnerabilities || [];
const uniqBasedOnId = new Set();
vulns.forEach(v => uniqBasedOnId.add(v.id));
vulnerabilities.forEach(v => uniqBasedOnId.add(v.id));
const fixable = vulnerabilities.some(({ isUpgradable }) => isUpgradable);

return {
...res.data,
packageName,
vulnerabilities,
packageName: `${name}@${version}`,
count: uniqBasedOnId.size,
fixable: vulns.reduce((acc, curr) => {
if (acc) return acc;
if (curr.isUpgradable) return true;
return false;
}, false),
fixable,
};
})
.catch(e => {
Expand Down

0 comments on commit 1170fd7

Please sign in to comment.