auditjs
Version:
Audit dependencies to identify known vulnerabilities and maintenance problems
140 lines • 5.71 kB
JavaScript
;
/*
* Copyright 2019-Present Sonatype Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.OssIndexRequestService = void 0;
const OssIndexCoordinates_1 = require("../Types/OssIndexCoordinates");
const node_persist_1 = __importDefault(require("node-persist"));
const path_1 = __importDefault(require("path"));
const os_1 = require("os");
const RequestHelpers_1 = require("./RequestHelpers");
const OSS_INDEX_BASE_URL = 'https://api.guide.sonatype.com/';
const COMPONENT_REPORT_ENDPOINT = 'api/v3/component-report';
const MAX_COORDINATES = 128;
const PATH = path_1.default.join((0, os_1.homedir)(), '.ossindex', 'auditjs');
const TWELVE_HOURS = 12 * 60 * 60 * 1000;
class OssIndexRequestService {
constructor(user, password, cacheLocation = PATH, baseURL = OSS_INDEX_BASE_URL) {
this.user = user;
this.password = password;
this.cacheLocation = cacheLocation;
this.baseURL = baseURL.endsWith('/') ? baseURL : baseURL + '/';
}
checkStatus(res) {
if (res.ok) {
return res;
}
throw new Error(`${res.statusText}`);
}
getHeaders() {
if (this.user && this.password) {
return [['Content-Type', 'application/json'], this.getBasicAuth(), RequestHelpers_1.RequestHelpers.getUserAgent()];
}
return [['Content-Type', 'application/json'], RequestHelpers_1.RequestHelpers.getUserAgent()];
}
getResultsFromOSSIndex(data) {
const response = fetch(`${this.baseURL}${COMPONENT_REPORT_ENDPOINT}`, {
method: 'post',
body: JSON.stringify(data),
headers: this.getHeaders(),
dispatcher: RequestHelpers_1.RequestHelpers.getHttpAgent(),
})
.then((res) => this.checkStatus(res))
.then((res) => res.json())
.catch((err) => {
throw new Error(`There was an error making the request: ${err}`);
});
return response;
}
chunkData(data) {
const chunks = [];
while (data.length > 0) {
chunks.push(data.splice(0, MAX_COORDINATES));
}
return chunks;
}
combineResponseChunks(data) {
return [].concat(...data);
}
combineCacheAndResponses(combinedChunks, dataInCache) {
return combinedChunks.concat(dataInCache);
}
async insertResponsesIntoCache(response) {
// console.debug(`Preparing to cache ${response.length} coordinate responses`);
for (let i = 0; i < response.length; i++) {
await node_persist_1.default.setItem(response[i].coordinates, response[i]);
}
// console.debug(`Done caching`);
return response;
}
async checkIfResultsAreInCache(data, format = 'npm') {
const inCache = new Array();
const notInCache = new Array();
for (let i = 0; i < data.length; i++) {
const coord = data[i];
const dataInCache = await node_persist_1.default.getItem(coord.toPurl(format));
if (dataInCache) {
inCache.push(dataInCache);
}
else {
notInCache.push(coord);
}
}
return new PurlContainer(inCache, notInCache);
}
/**
* Posts to OSS Index {@link COMPONENT_REPORT_ENDPOINT}, returns Promise of json object of response
* @param data - {@link Coordinates} Array
* @returns a {@link Promise} of all Responses
*/
async callOSSIndexOrGetFromCache(data, format = 'npm') {
await node_persist_1.default.init({ dir: this.cacheLocation, ttl: TWELVE_HOURS });
const responses = [];
// console.debug(`Purls received, total purls before chunk: ${data.length}`);
const results = await this.checkIfResultsAreInCache(data, format);
const chunkedPurls = this.chunkData(results.notInCache);
for (const chunk of chunkedPurls) {
try {
const res = this.getResultsFromOSSIndex(new OssIndexCoordinates_1.OssIndexCoordinates(chunk.map((x) => x.toPurl(format))));
responses.push(res);
}
catch (e) {
throw new Error(String(e));
}
}
return Promise.all(responses)
.then((resolvedResponses) => this.combineResponseChunks(resolvedResponses))
.then((combinedResponses) => this.insertResponsesIntoCache(combinedResponses))
.then((combinedResponses) => this.combineCacheAndResponses(combinedResponses, results.inCache))
.catch((err) => {
throw err;
});
}
getBasicAuth() {
return ['Authorization', 'Basic ' + Buffer.from(this.user + ':' + this.password).toString('base64')];
}
}
exports.OssIndexRequestService = OssIndexRequestService;
class PurlContainer {
constructor(inCache, notInCache) {
this.inCache = inCache;
this.notInCache = notInCache;
}
}
//# sourceMappingURL=OssIndexRequestService.js.map