@dxdeveloperexperience/hygie
Version:
Hygie is an easy-to-use Open-Source REST API allowing you to interact with GIT events. This NestJS API expose a set of customizable rules to automate your project's life cycle.
118 lines (103 loc) • 3.37 kB
text/typescript
import { Rule } from './rule.class';
import { RuleResult } from './ruleResult';
import { GitEventEnum } from '../webhook/utils.enum';
import { Webhook } from '../webhook/webhook';
import { RuleDecorator } from './rule.decorator';
import { logger } from '../logger/logger.service';
import { RemoteConfigUtils } from '../remote-config/utils';
import { Inject } from '@nestjs/common';
import { Visitor } from 'universal-analytics';
interface CheckVulnerabilitiesOptions {
packageUrl: string;
packageLockUrl: string;
}
/**
* `CheckVulnerabilitiesRule` will check if `package.json` and `package-lock.json` contain vulnerabilities thank's to `npm audit`.
* @return return a `RuleResult` object
*/
('checkVulnerabilities')
export class CheckVulnerabilitiesRule extends Rule {
options: CheckVulnerabilitiesOptions;
events = [GitEventEnum.Push, GitEventEnum.Cron];
constructor(
('GoogleAnalytics')
private readonly googleAnalytics: Visitor,
) {
super();
}
getNumberOfVulnerabilities(data: any): number {
const vulnerabilities = data.metadata.vulnerabilities;
return (
vulnerabilities.info +
vulnerabilities.low +
vulnerabilities.moderate +
vulnerabilities.high +
vulnerabilities.critical
);
}
async validate(
webhook: Webhook,
ruleConfig: CheckVulnerabilitiesRule,
ruleResults?: RuleResult[],
): Promise<RuleResult> {
const ruleResult: RuleResult = new RuleResult(
webhook.getGitApiInfos(),
webhook.getCloneURL(),
);
this.googleAnalytics
.event('Rule', 'checkVulnerabilities', webhook.getCloneURL())
.send();
const execa = require('execa');
const download = require('download');
const fs = require('fs-extra');
let audit: any;
let packageUrl: string;
let packageLockUrl: string;
if (
typeof ruleConfig.options !== 'undefined' &&
typeof ruleConfig.options.packageUrl !== 'undefined' &&
typeof ruleConfig.options.packageLockUrl !== 'undefined'
) {
packageUrl = ruleConfig.options.packageUrl;
packageLockUrl = ruleConfig.options.packageLockUrl;
} else {
packageUrl = RemoteConfigUtils.getGitRawPath(
webhook.getGitType(),
webhook.getCloneURL(),
'package.json',
);
packageLockUrl = RemoteConfigUtils.getGitRawPath(
webhook.getGitType(),
webhook.getCloneURL(),
'package-lock.json',
);
}
await Promise.all([
download(packageUrl, `packages/${webhook.getRemoteDirectory()}`),
download(packageLockUrl, `packages/${webhook.getRemoteDirectory()}`),
]);
try {
audit = execa.shellSync(
`cd packages/${webhook.getRemoteDirectory()} & npm audit --json`,
);
ruleResult.data = {
vulnerabilities: JSON.parse(audit.stdout),
};
ruleResult.validated = true;
} catch (e) {
const data = JSON.parse(e.stdout);
ruleResult.data = {
number: this.getNumberOfVulnerabilities(data),
vulnerabilities: JSON.stringify(data),
};
ruleResult.validated = false;
}
// Delete folder
fs.remove(`packages/${webhook.getRemoteDirectory().split('/')[0]}`).catch(
err => {
logger.error(err, { location: 'checkVulnerabilities' });
},
);
return ruleResult;
}
}