From f96b147ea128209045e95a26bfcfc17d0f08aa8f Mon Sep 17 00:00:00 2001 From: Simon Lorenz Date: Thu, 2 Sep 2021 22:24:31 +0200 Subject: [PATCH] fix: resolves several issues of audit plugin (#2400) * fixes an ssl error by correcting the host header * fixes an `413 - entity too large` / `400 -Invalid compressed payload` error by explicitly setting the content-encoding header * sends json body to remote registry * adds new `/advisories/bulk` endpoint * respects `strict_ssl` setting Co-authored-by: Juan Picado --- .changeset/little-stingrays-rule.md | 5 ++++ packages/plugins/audit/src/audit.ts | 45 ++++++++++++++--------------- 2 files changed, 27 insertions(+), 23 deletions(-) create mode 100644 .changeset/little-stingrays-rule.md diff --git a/.changeset/little-stingrays-rule.md b/.changeset/little-stingrays-rule.md new file mode 100644 index 000000000000..00feec3ec0c0 --- /dev/null +++ b/.changeset/little-stingrays-rule.md @@ -0,0 +1,5 @@ +--- +'verdaccio-audit': patch +--- + +fix: several issues which caused the audit to fail (#2335) diff --git a/packages/plugins/audit/src/audit.ts b/packages/plugins/audit/src/audit.ts index 9277b9e55c49..042e050c03fa 100644 --- a/packages/plugins/audit/src/audit.ts +++ b/packages/plugins/audit/src/audit.ts @@ -1,4 +1,3 @@ -import util from 'util'; import https from 'https'; import fetch from 'node-fetch'; @@ -6,17 +5,11 @@ import createHttpsProxyAgent from 'https-proxy-agent'; import express, { Request, Response } from 'express'; import { Logger, IPluginMiddleware, IBasicAuth, PluginOptions } from '@verdaccio/types'; +import { json as jsonParser } from 'body-parser'; import { ConfigAudit } from './types'; -const streamPipeline = util.promisify(require('stream').pipeline); - // FUTURE: we should be able to overwrite this export const REGISTRY_DOMAIN = 'https://registry.npmjs.org'; -export const AUDIT_ENDPOINT = `/-/npm/v1/security/audits`; - -function getSSLAgent(rejectUnauthorized) { - return new https.Agent({ rejectUnauthorized }); -} export default class ProxyAudit implements IPluginMiddleware<{}> { public enabled: boolean; @@ -32,19 +25,17 @@ export default class ProxyAudit implements IPluginMiddleware<{}> { public register_middlewares(app: any, auth: IBasicAuth): void { const fetchAudit = (req: Request, res: Response & { report_error?: Function }): void => { const headers = req.headers; - headers.host = 'https://registry.npmjs.org/'; + + headers['host'] = 'registry.npmjs.org'; + headers['content-encoding'] = 'gzip,deflate,br'; let requestOptions: any = { - method: req.method, + agent: new https.Agent({ rejectUnauthorized: this.strict_ssl }), + body: JSON.stringify(req.body), headers, + method: req.method, }; - if (this.strict_ssl) { - requestOptions = Object.assign({}, requestOptions, { - agent: getSSLAgent(this.strict_ssl), - }); - } - if (auth?.config?.https_proxy) { // we should check whether this works fine after this migration // please notify if anyone is having issues @@ -56,13 +47,19 @@ export default class ProxyAudit implements IPluginMiddleware<{}> { (async () => { try { - const response = await fetch(`${REGISTRY_DOMAIN}${AUDIT_ENDPOINT}`, requestOptions); + const auditEndpoint = `${REGISTRY_DOMAIN}${req.baseUrl}${req.route.path}`; + this.logger.debug('fetching audit from ' + auditEndpoint); + + const response = await fetch(auditEndpoint, requestOptions); + if (response.ok) { - return streamPipeline(response.body, res); + res.status(response.status).send(await response.json()); + } else { + this.logger.warn('could not fetch audit: ' + JSON.stringify(await response.json())); + res.status(response.status).end(); } - - res.status(response.status).end(); - } catch { + } catch (error) { + this.logger.warn('could not fetch audit: ' + error); res.status(500).end(); } })(); @@ -79,9 +76,11 @@ export default class ProxyAudit implements IPluginMiddleware<{}> { /* eslint new-cap:off */ const router = express.Router(); /* eslint new-cap:off */ - router.post('/audits', handleAudit); - router.post('/audits/quick', handleAudit); + router.post('/audits', jsonParser({ limit: '10mb' }), handleAudit); + router.post('/audits/quick', jsonParser({ limit: '10mb' }), handleAudit); + + router.post('/advisories/bulk', jsonParser({ limit: '10mb' }), handleAudit); app.use('/-/npm/v1/security', router); }