@contrast/contrast 1.0.2 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/.prettierignore +4 -0
  2. package/README.md +24 -16
  3. package/dist/audit/autodetection/autoDetectLanguage.js +32 -0
  4. package/dist/audit/catalogueApplication/catalogueApplication.js +2 -11
  5. package/dist/audit/languageAnalysisEngine/{langugageAnalysisFactory.js → languageAnalysisFactory.js} +30 -13
  6. package/dist/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +25 -0
  7. package/dist/audit/languageAnalysisEngine/report/commonReportingFunctions.js +51 -237
  8. package/dist/audit/languageAnalysisEngine/report/models/reportLibraryModel.js +19 -0
  9. package/dist/audit/languageAnalysisEngine/report/models/reportListModel.js +24 -0
  10. package/dist/audit/languageAnalysisEngine/report/models/reportSeverityModel.js +10 -0
  11. package/dist/audit/languageAnalysisEngine/report/reportingFeature.js +24 -129
  12. package/dist/audit/languageAnalysisEngine/report/utils/reportUtils.js +85 -0
  13. package/dist/audit/languageAnalysisEngine/sendSnapshot.js +2 -14
  14. package/dist/commands/audit/auditConfig.js +8 -2
  15. package/dist/commands/audit/auditController.js +14 -5
  16. package/dist/commands/audit/saveFile.js +11 -0
  17. package/dist/commands/auth/auth.js +19 -1
  18. package/dist/commands/config/config.js +19 -8
  19. package/dist/commands/scan/processScan.js +13 -27
  20. package/dist/commands/scan/sca/scaAnalysis.js +44 -0
  21. package/dist/common/HTTPClient.js +29 -26
  22. package/dist/common/errorHandling.js +15 -39
  23. package/dist/common/versionChecker.js +32 -0
  24. package/dist/constants/constants.js +16 -2
  25. package/dist/constants/lambda.js +3 -1
  26. package/dist/constants/locales.js +58 -48
  27. package/dist/constants.js +59 -3
  28. package/dist/index.js +48 -30
  29. package/dist/lambda/help.js +22 -14
  30. package/dist/lambda/lambda.js +6 -0
  31. package/dist/sbom/generateSbom.js +20 -0
  32. package/dist/scaAnalysis/common/formatMessage.js +11 -0
  33. package/dist/scaAnalysis/common/treeUpload.js +30 -0
  34. package/dist/scaAnalysis/java/analysis.js +116 -0
  35. package/dist/scaAnalysis/java/index.js +18 -0
  36. package/dist/scaAnalysis/java/javaBuildDepsParser.js +326 -0
  37. package/dist/scan/autoDetection.js +46 -1
  38. package/dist/scan/fileUtils.js +73 -1
  39. package/dist/scan/formatScanOutput.js +212 -0
  40. package/dist/scan/help.js +6 -2
  41. package/dist/scan/models/groupedResultsModel.js +11 -0
  42. package/dist/scan/models/resultContentModel.js +2 -0
  43. package/dist/scan/models/scanResultsModel.js +11 -0
  44. package/dist/scan/populateProjectIdAndProjectName.js +1 -0
  45. package/dist/scan/saveResults.js +9 -10
  46. package/dist/scan/scan.js +26 -101
  47. package/dist/scan/scanConfig.js +20 -1
  48. package/dist/scan/scanController.js +8 -4
  49. package/dist/scan/scanResults.js +8 -17
  50. package/dist/utils/getConfig.js +3 -0
  51. package/dist/utils/requestUtils.js +1 -1
  52. package/dist/utils/saveFile.js +19 -0
  53. package/package.json +3 -2
  54. package/src/audit/autodetection/autoDetectLanguage.ts +40 -0
  55. package/src/audit/catalogueApplication/catalogueApplication.js +4 -16
  56. package/src/audit/languageAnalysisEngine/{langugageAnalysisFactory.js → languageAnalysisFactory.js} +41 -19
  57. package/src/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +71 -0
  58. package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.ts +105 -0
  59. package/src/audit/languageAnalysisEngine/report/models/reportLibraryModel.ts +30 -0
  60. package/src/audit/languageAnalysisEngine/report/models/reportListModel.ts +32 -0
  61. package/src/audit/languageAnalysisEngine/report/models/reportSeverityModel.ts +9 -0
  62. package/src/audit/languageAnalysisEngine/report/reportingFeature.ts +56 -0
  63. package/src/audit/languageAnalysisEngine/report/utils/reportUtils.ts +110 -0
  64. package/src/audit/languageAnalysisEngine/sendSnapshot.js +2 -22
  65. package/src/commands/audit/auditConfig.ts +12 -3
  66. package/src/commands/audit/auditController.ts +21 -5
  67. package/src/commands/audit/processAudit.ts +3 -1
  68. package/src/commands/audit/saveFile.ts +6 -0
  69. package/src/commands/auth/auth.js +25 -1
  70. package/src/commands/config/config.js +22 -8
  71. package/src/commands/scan/processScan.js +15 -31
  72. package/src/commands/scan/sca/scaAnalysis.js +73 -0
  73. package/src/common/HTTPClient.js +42 -36
  74. package/src/common/errorHandling.ts +17 -48
  75. package/src/common/versionChecker.ts +41 -0
  76. package/src/constants/constants.js +17 -4
  77. package/src/constants/lambda.js +3 -1
  78. package/src/constants/locales.js +69 -63
  79. package/src/constants.js +66 -3
  80. package/src/index.ts +62 -36
  81. package/src/lambda/help.ts +22 -14
  82. package/src/lambda/lambda.ts +8 -0
  83. package/src/sbom/generateSbom.ts +17 -0
  84. package/src/scaAnalysis/common/formatMessage.js +10 -0
  85. package/src/scaAnalysis/common/treeUpload.js +34 -0
  86. package/src/scaAnalysis/java/analysis.js +159 -0
  87. package/src/scaAnalysis/java/index.js +21 -0
  88. package/src/scaAnalysis/java/javaBuildDepsParser.js +391 -0
  89. package/src/scan/autoDetection.js +54 -1
  90. package/src/scan/fileUtils.js +91 -1
  91. package/src/scan/formatScanOutput.ts +241 -0
  92. package/src/scan/help.js +6 -2
  93. package/src/scan/models/groupedResultsModel.ts +20 -0
  94. package/src/scan/models/resultContentModel.ts +86 -0
  95. package/src/scan/models/scanResultsModel.ts +52 -0
  96. package/src/scan/populateProjectIdAndProjectName.js +1 -0
  97. package/src/scan/saveResults.js +8 -9
  98. package/src/scan/scan.ts +62 -0
  99. package/src/scan/scanConfig.js +26 -1
  100. package/src/scan/scanController.js +12 -4
  101. package/src/scan/scanResults.js +19 -17
  102. package/src/utils/getConfig.ts +12 -0
  103. package/src/utils/requestUtils.js +1 -1
  104. package/src/utils/saveFile.js +19 -0
  105. package/dist/audit/languageAnalysisEngine/report/checkIgnoreDevDep.js +0 -17
  106. package/dist/audit/languageAnalysisEngine/report/newReportingFeature.js +0 -81
  107. package/dist/common/findLatestCLIVersion.js +0 -23
  108. package/src/audit/languageAnalysisEngine/report/checkIgnoreDevDep.js +0 -27
  109. package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.js +0 -303
  110. package/src/audit/languageAnalysisEngine/report/newReportingFeature.js +0 -124
  111. package/src/audit/languageAnalysisEngine/report/reportingFeature.js +0 -190
  112. package/src/common/findLatestCLIVersion.ts +0 -27
  113. package/src/scan/scan.js +0 -167
@@ -1,133 +1,28 @@
1
1
  "use strict";
2
- const i18n = require('i18n');
3
- const commonApi = require('../commonApi');
4
- const commonReport = require('./commonReportingFunctions');
5
- function displaySuccessMessageVulnerabilities() {
6
- console.log(i18n.__('vulnerabilitiesSuccessMessage'));
7
- }
8
- const vulnerabilityReport = async (analysis, applicationId, config) => {
9
- let depRiskReportCount = {};
10
- if (analysis.language === 'NODE') {
11
- depRiskReportCount = await commonReport.dependencyRiskReport(analysis.node.packageJSON, config);
12
- }
13
- if (config['report']) {
14
- const reportResponse = await commonReport.getReport(applicationId);
15
- if (reportResponse !== undefined) {
16
- const libraryVulnerabilityInput = createLibraryVulnerabilityInput(reportResponse.reports);
17
- const libraryVulnerabilityResponse = await getLibraryVulnerabilities(libraryVulnerabilityInput, applicationId);
18
- const severity = config['cve_severity'];
19
- const id = applicationId;
20
- const name = config.applicationName;
21
- const hasSomeVulnerabilitiesReported = formatVulnerabilityOutput(libraryVulnerabilityResponse, severity, id, name, depRiskReportCount, config);
22
- commonReport.analyseReportOptions(hasSomeVulnerabilitiesReported);
23
- }
24
- }
25
- };
26
- const createLibraryVulnerabilityInput = report => {
27
- const language = Object.keys(report[0].report)[0];
28
- const reportTree = report[0].report[language].dependencyTree;
29
- const libraries = reportTree[Object.keys(reportTree)[0]];
30
- let gav = [];
31
- for (const key of Object.keys(libraries)) {
32
- gav.push({
33
- name: libraries[key].name,
34
- group: libraries[key].group,
35
- version: libraries[key].resolved
36
- });
37
- }
38
- return {
39
- name_group_versions: gav,
40
- language: language.toUpperCase()
41
- };
42
- };
43
- const oldCountSeverity = vulnerableLibraries => {
44
- const severityCount = {
45
- critical: 0,
46
- high: 0,
47
- medium: 0,
48
- low: 0
49
- };
50
- vulnerableLibraries.forEach(lib => {
51
- lib.vulns.forEach(vuln => {
52
- if (vuln.severity_code === 'HIGH') {
53
- severityCount['high'] += 1;
54
- }
55
- else if (vuln.severity_code === 'MEDIUM') {
56
- severityCount['medium'] += 1;
57
- }
58
- else if (vuln.severity_code === 'LOW') {
59
- severityCount['low'] += 1;
60
- }
61
- else if (vuln.severity_code === 'CRITICAL') {
62
- severityCount['critical'] += 1;
63
- }
64
- });
65
- });
66
- return severityCount;
67
- };
68
- const parseVulnerabilites = libraryVulnerabilityResponse => {
69
- let parsedVulnerabilites = {};
70
- let vulnName = libraryVulnerabilityResponse.libraries;
71
- for (let x in vulnName) {
72
- let vuln = vulnName[x].vulns;
73
- if (vuln.length > 0) {
74
- let libname = vulnName[x].group +
75
- '/' +
76
- vulnName[x].file_name +
77
- '@' +
78
- vulnName[x].file_version;
79
- parsedVulnerabilites[libname] = vulnName[x].vulns;
80
- }
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.formatVulnerabilityOutput = exports.vulnerabilityReport = void 0;
4
+ const commonReportingFunctions_1 = require("./commonReportingFunctions");
5
+ const reportUtils_1 = require("./utils/reportUtils");
6
+ async function vulnerabilityReport(analysis, applicationId, reportId) {
7
+ const reportResponse = await (0, commonReportingFunctions_1.getReport)(analysis.config, reportId);
8
+ if (reportResponse !== undefined) {
9
+ const id = applicationId;
10
+ const name = analysis.config.applicationName;
11
+ formatVulnerabilityOutput(reportResponse.vulnerabilities, id, name, analysis.config);
81
12
  }
82
- return parsedVulnerabilites;
83
- };
84
- const formatVulnerabilityOutput = (libraryVulnerabilityResponse, severity, id, name, depRiskReportCount, config) => {
85
- let vulnerableLibraries = libraryVulnerabilityResponse.libraries.filter(data => {
86
- return data.vulns.length > 0;
87
- });
13
+ }
14
+ exports.vulnerabilityReport = vulnerabilityReport;
15
+ function formatVulnerabilityOutput(libraryVulnerabilityResponse, id, name, config) {
16
+ const vulnerableLibraries = (0, reportUtils_1.convertGenericToTypedLibraries)(libraryVulnerabilityResponse);
88
17
  const numberOfVulnerableLibraries = vulnerableLibraries.length;
89
18
  let numberOfCves = 0;
90
- vulnerableLibraries.forEach(lib => (numberOfCves += lib.vulns.length));
91
- commonReport.createLibraryHeader(id, numberOfVulnerableLibraries, numberOfCves, name);
92
- const severityCount = oldCountSeverity(vulnerableLibraries);
93
- let vulnerabilities = parseVulnerabilites(libraryVulnerabilityResponse);
94
- let filteredVulns = commonReport.filterVulnerabilitiesBySeverity(severity, vulnerabilities);
95
- let hasSomeVulnerabilitiesReported;
96
- hasSomeVulnerabilitiesReported = commonReport.printVulnerabilityResponse(severity, filteredVulns, vulnerabilities);
97
- console.log('\n **************************' +
98
- ` Found ${numberOfVulnerableLibraries} vulnerable libraries containing ${numberOfCves} CVE's ` +
99
- '************************** ');
100
- if (depRiskReportCount && depRiskReportCount.scopedCount === 0) {
101
- console.log(' No private libraries that are not scoped detected');
102
- }
103
- console.log(' \n Please go to the Contrast UI to view your dependency tree: \n' +
104
- ` \n ${config.host}/Contrast/static/ng/index.html#/${config.organizationId}/applications/${config.applicationId}/libs/dependency-tree`);
105
- return [hasSomeVulnerabilitiesReported, numberOfCves, severityCount];
106
- };
107
- const getLibraryVulnerabilities = async (input, applicationId) => {
108
- const requestBody = input;
109
- const addParams = agent.getAdditionalParams();
110
- const userParams = await util.getParams(applicationId);
111
- const protocol = getValidHost(userParams.host);
112
- const client = commonApi.getHttpClient(userParams, protocol, addParams);
113
- return client
114
- .getLibraryVulnerabilities(requestBody, userParams)
115
- .then(res => {
116
- if (res.statusCode === 200) {
117
- displaySuccessMessageVulnerabilities();
118
- return res.body;
119
- }
120
- else {
121
- handleResponseErrors(res, 'vulnerabilities');
122
- }
123
- })
124
- .catch(err => {
125
- console.log(err);
126
- });
127
- };
128
- module.exports = {
129
- vulnerabilityReport: vulnerabilityReport,
130
- getLibraryVulnerabilities: getLibraryVulnerabilities,
131
- formatVulnerabilityOutput: formatVulnerabilityOutput,
132
- createLibraryVulnerabilityInput: createLibraryVulnerabilityInput
133
- };
19
+ vulnerableLibraries.forEach(lib => (numberOfCves += lib.cveArray.length));
20
+ (0, commonReportingFunctions_1.createLibraryHeader)(id, numberOfVulnerableLibraries, numberOfCves);
21
+ const hasSomeVulnerabilitiesReported = (0, commonReportingFunctions_1.printVulnerabilityResponse)(vulnerableLibraries, config);
22
+ return [
23
+ hasSomeVulnerabilitiesReported,
24
+ numberOfCves,
25
+ (0, reportUtils_1.severityCount)(vulnerableLibraries)
26
+ ];
27
+ }
28
+ exports.formatVulnerabilityOutput = formatVulnerabilityOutput;
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.findNameAndVersion = exports.severityCount = exports.convertGenericToTypedLibraries = exports.findHighestSeverityCVE = void 0;
7
+ const reportLibraryModel_1 = require("../models/reportLibraryModel");
8
+ const reportSeverityModel_1 = require("../models/reportSeverityModel");
9
+ const constants_1 = __importDefault(require("../../../languageAnalysisEngine/constants"));
10
+ const { supportedLanguages: { GO } } = constants_1.default;
11
+ function findHighestSeverityCVE(cveArray) {
12
+ if (cveArray.find(cve => cve.cvss3SeverityCode === 'CRITICAL' || cve.severityCode === 'CRITICAL')) {
13
+ return new reportSeverityModel_1.ReportSeverityModel('CRITICAL', 1);
14
+ }
15
+ else if (cveArray.find(cve => cve.cvss3SeverityCode === 'HIGH' || cve.severityCode === 'HIGH')) {
16
+ return new reportSeverityModel_1.ReportSeverityModel('HIGH', 2);
17
+ }
18
+ else if (cveArray.find(cve => cve.cvss3SeverityCode === 'MEDIUM' || cve.severityCode === 'MEDIUM')) {
19
+ return new reportSeverityModel_1.ReportSeverityModel('MEDIUM', 3);
20
+ }
21
+ else if (cveArray.find(cve => cve.cvss3SeverityCode === 'LOW' || cve.severityCode === 'LOW')) {
22
+ return new reportSeverityModel_1.ReportSeverityModel('LOW', 4);
23
+ }
24
+ else if (cveArray.find(cve => cve.cvss3SeverityCode === 'NOTE' || cve.severityCode === 'NOTE')) {
25
+ return new reportSeverityModel_1.ReportSeverityModel('NOTE', 5);
26
+ }
27
+ }
28
+ exports.findHighestSeverityCVE = findHighestSeverityCVE;
29
+ function convertGenericToTypedLibraries(libraries) {
30
+ return Object.entries(libraries).map(([name, cveArray]) => {
31
+ return new reportLibraryModel_1.ReportLibraryModel(name, cveArray);
32
+ });
33
+ }
34
+ exports.convertGenericToTypedLibraries = convertGenericToTypedLibraries;
35
+ function severityCount(vulnerableLibraries) {
36
+ const severityCount = {
37
+ critical: 0,
38
+ high: 0,
39
+ medium: 0,
40
+ low: 0,
41
+ note: 0
42
+ };
43
+ vulnerableLibraries.forEach(lib => {
44
+ lib.cveArray.forEach(cve => {
45
+ if (cve.cvss3SeverityCode === 'CRITICAL' ||
46
+ cve.severityCode === 'CRITICAL') {
47
+ severityCount['critical'] += 1;
48
+ }
49
+ else if (cve.cvss3SeverityCode === 'HIGH' ||
50
+ cve.severityCode === 'HIGH') {
51
+ severityCount['high'] += 1;
52
+ }
53
+ else if (cve.cvss3SeverityCode === 'MEDIUM' ||
54
+ cve.severityCode === 'MEDIUM') {
55
+ severityCount['medium'] += 1;
56
+ }
57
+ else if (cve.cvss3SeverityCode === 'LOW' ||
58
+ cve.severityCode === 'LOW') {
59
+ severityCount['low'] += 1;
60
+ }
61
+ else if (cve.cvss3SeverityCode === 'NOTE' ||
62
+ cve.severityCode === 'NOTE') {
63
+ severityCount['note'] += 1;
64
+ }
65
+ });
66
+ });
67
+ return severityCount;
68
+ }
69
+ exports.severityCount = severityCount;
70
+ function findNameAndVersion(library, config) {
71
+ if (config.language.toUpperCase() === GO) {
72
+ const nameVersion = library.name.split('@');
73
+ const name = nameVersion[0];
74
+ const version = nameVersion[1];
75
+ return { name, version };
76
+ }
77
+ else {
78
+ const splitLibraryName = library.name.split('/');
79
+ const nameVersion = splitLibraryName[1].split('@');
80
+ const name = nameVersion[0];
81
+ const version = nameVersion[1];
82
+ return { name, version };
83
+ }
84
+ }
85
+ exports.findNameAndVersion = findNameAndVersion;
@@ -1,18 +1,8 @@
1
1
  "use strict";
2
- const prettyjson = require('prettyjson');
3
- const i18n = require('i18n');
4
2
  const { getHttpClient } = require('../../utils/commonApi');
5
3
  const { handleResponseErrors } = require('../../common/errorHandling');
6
4
  const { APP_VERSION } = require('../../constants/constants');
7
- function displaySnapshotSuccessMessage(config) {
8
- console.log('\n **************************' +
9
- i18n.__('successHeader') +
10
- '************************** ');
11
- console.log('\n' + i18n.__('snapshotSuccessMessage') + '\n');
12
- console.log(` ${config.host}/Contrast/static/ng/index.html#/${config.organizationId}/applications/${config.applicationId}/libs/dependency-tree`);
13
- console.log('\n ***********************************************************');
14
- }
15
- const newSendSnapShot = async (analysis, applicationId) => {
5
+ const newSendSnapShot = async (analysis) => {
16
6
  const analysisLanguage = analysis.config.language.toLowerCase();
17
7
  const requestBody = {
18
8
  appID: analysis.config.applicationId,
@@ -24,7 +14,6 @@ const newSendSnapShot = async (analysis, applicationId) => {
24
14
  .sendSnapshot(requestBody, analysis.config)
25
15
  .then(res => {
26
16
  if (res.statusCode === 201) {
27
- displaySnapshotSuccessMessage(analysis.config);
28
17
  return res.body;
29
18
  }
30
19
  else {
@@ -36,6 +25,5 @@ const newSendSnapShot = async (analysis, applicationId) => {
36
25
  });
37
26
  };
38
27
  module.exports = {
39
- newSendSnapShot: newSendSnapShot,
40
- displaySnapshotSuccessMessage: displaySnapshotSuccessMessage
28
+ newSendSnapShot: newSendSnapShot
41
29
  };
@@ -8,14 +8,20 @@ const paramHandler_1 = __importDefault(require("../../utils/paramsUtil/paramHand
8
8
  const constants_1 = __importDefault(require("../../constants"));
9
9
  const parsedCLIOptions_1 = __importDefault(require("../../utils/parsedCLIOptions"));
10
10
  const constants_2 = __importDefault(require("../../audit/languageAnalysisEngine/constants"));
11
+ const autoDetectLanguage_1 = require("../../audit/autodetection/autoDetectLanguage");
11
12
  const { supportedLanguages: { NODE, JAVASCRIPT } } = constants_2.default;
12
13
  const getAuditConfig = (argv) => {
13
14
  const auditParameters = parsedCLIOptions_1.default.getCommandLineArgsCustom(argv, constants_1.default.commandLineDefinitions.auditOptionDefinitions);
14
15
  const paramsAuth = paramHandler_1.default.getAuth(auditParameters);
15
16
  if (auditParameters.language === undefined ||
16
17
  auditParameters.language === null) {
17
- console.log('error, --language parameter is required');
18
- process.exit(1);
18
+ try {
19
+ auditParameters.language = (0, autoDetectLanguage_1.determineProjectLanguage)((0, autoDetectLanguage_1.identifyLanguages)(auditParameters));
20
+ }
21
+ catch (err) {
22
+ console.log(err.message);
23
+ process.exit(1);
24
+ }
19
25
  }
20
26
  else if (auditParameters.language.toUpperCase() === JAVASCRIPT) {
21
27
  auditParameters.language = NODE.toLowerCase();
@@ -3,11 +3,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.startAudit = void 0;
6
+ exports.startAudit = exports.dealWithNoAppId = void 0;
7
7
  const catalogueApplication_1 = require("../../audit/catalogueApplication/catalogueApplication");
8
8
  const commonApi_1 = __importDefault(require("../../audit/languageAnalysisEngine/commonApi"));
9
9
  const identifyLanguageAE = require('./../../audit/languageAnalysisEngine');
10
- const languageFactory = require('./../../audit/languageAnalysisEngine/langugageAnalysisFactory');
10
+ const languageFactory = require('../../audit/languageAnalysisEngine/languageAnalysisFactory');
11
+ const { v4: uuidv4 } = require('uuid');
11
12
  const dealWithNoAppId = async (config) => {
12
13
  let appID;
13
14
  try {
@@ -15,16 +16,24 @@ const dealWithNoAppId = async (config) => {
15
16
  if (!appID && config.applicationName) {
16
17
  return await (0, catalogueApplication_1.catalogueApplication)(config);
17
18
  }
19
+ if (!appID && !config.applicationName) {
20
+ config.applicationName = uuidv4();
21
+ return await (0, catalogueApplication_1.catalogueApplication)(config);
22
+ }
18
23
  }
19
24
  catch (e) {
20
- console.log(e);
25
+ if (e.toString().includes('tunneling socket could not be established')) {
26
+ console.log(e.message);
27
+ console.log('There seems to be an issue with your proxy, please check and try again');
28
+ }
29
+ process.exit(1);
21
30
  }
22
- console.log(appID);
23
31
  return appID;
24
32
  };
33
+ exports.dealWithNoAppId = dealWithNoAppId;
25
34
  const startAudit = async (config) => {
26
35
  if (!config.applicationId) {
27
- config.applicationId = await dealWithNoAppId(config);
36
+ config.applicationId = await (0, exports.dealWithNoAppId)(config);
28
37
  }
29
38
  identifyLanguageAE(config.projectPath, languageFactory, config.applicationId, config);
30
39
  };
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const fs_1 = __importDefault(require("fs"));
7
+ function saveFile(config, rawResults) {
8
+ const fileName = `${config.applicationId}-sbom-cyclonedx.json`;
9
+ fs_1.default.writeFileSync(fileName, JSON.stringify(rawResults));
10
+ }
11
+ exports.default = saveFile;
@@ -7,7 +7,15 @@ const { sleep } = require('../../utils/requestUtils');
7
7
  const i18n = require('i18n');
8
8
  const { returnOra, startSpinner, failSpinner, succeedSpinner } = require('../../utils/oraWrapper');
9
9
  const { TIMEOUT, AUTH_UI_URL } = require('../../constants/constants');
10
- const processAuth = async (config) => {
10
+ const parsedCLIOptions = require('../../utils/parsedCLIOptions');
11
+ const constants = require('../../constants');
12
+ const commandLineUsage = require('command-line-usage');
13
+ const processAuth = async (argv, config) => {
14
+ let authParams = parsedCLIOptions.getCommandLineArgsCustom(argv, constants.commandLineDefinitions.authOptionDefinitions);
15
+ if (authParams.help) {
16
+ console.log(authUsageGuide);
17
+ process.exit(0);
18
+ }
11
19
  const token = uuidv4();
12
20
  const url = `${AUTH_UI_URL}/?token=${token}`;
13
21
  console.log(i18n.__('redirectAuth', url));
@@ -56,6 +64,16 @@ const pollAuthResult = async (token, client) => {
56
64
  console.log(err);
57
65
  });
58
66
  };
67
+ const authUsageGuide = commandLineUsage([
68
+ {
69
+ header: i18n.__('authHeader'),
70
+ content: [i18n.__('constantsAuthHeaderContents')]
71
+ },
72
+ {
73
+ header: i18n.__('constantsAuthUsageHeader'),
74
+ content: [i18n.__('constantsAuthUsageContents')]
75
+ }
76
+ ]);
59
77
  module.exports = {
60
78
  processAuth: processAuth
61
79
  };
@@ -1,14 +1,16 @@
1
1
  "use strict";
2
- const commandLineArgs = require('command-line-args');
2
+ const parsedCLIOptions = require('../../utils/parsedCLIOptions');
3
+ const constants = require('../../constants');
4
+ const commandLineUsage = require('command-line-usage');
5
+ const i18n = require('i18n');
3
6
  const processConfig = (argv, config) => {
4
- const options = [{ name: 'clear', alias: 'c', type: Boolean }];
5
7
  try {
6
- const configOptions = commandLineArgs(options, {
7
- argv,
8
- caseInsensitive: true,
9
- camelCase: true
10
- });
11
- if (configOptions.clear) {
8
+ let configParams = parsedCLIOptions.getCommandLineArgsCustom(argv, constants.commandLineDefinitions.configOptionDefinitions);
9
+ if (configParams.help) {
10
+ console.log(configUsageGuide);
11
+ process.exit(0);
12
+ }
13
+ if (configParams.clear) {
12
14
  config.clear();
13
15
  }
14
16
  else {
@@ -19,6 +21,15 @@ const processConfig = (argv, config) => {
19
21
  console.log(e.message.toString());
20
22
  }
21
23
  };
24
+ const configUsageGuide = commandLineUsage([
25
+ {
26
+ header: i18n.__('configHeader')
27
+ },
28
+ {
29
+ content: [i18n.__('constantsConfigUsageContents')],
30
+ optionList: constants.commandLineDefinitions.configOptionDefinitions
31
+ }
32
+ ]);
22
33
  module.exports = {
23
34
  processConfig: processConfig
24
35
  };
@@ -1,37 +1,23 @@
1
1
  "use strict";
2
- const { startScan } = require('../../scan/scanController');
3
- const { formatScanOutput } = require('../../scan/scan');
4
- const { scanUsageGuide } = require('../../scan/help');
5
2
  const scanConfig = require('../../scan/scanConfig');
6
- const saveResults = require('../../scan/saveResults');
7
- const commonApi = require('../../utils/commonApi');
8
- const i18n = require('i18n');
3
+ const { startScan } = require('../../scan/scanController');
4
+ const { saveScanFile } = require('../../utils/saveFile');
5
+ const { ScanResultsModel } = require('../../scan/models/scanResultsModel');
6
+ const { formatScanOutput } = require('../../scan/formatScanOutput');
7
+ const { processSca } = require('./sca/scaAnalysis');
9
8
  const processScan = async (argvMain) => {
10
- if (argvMain.indexOf('--help') !== -1) {
11
- printHelpMessage();
12
- process.exit(1);
13
- }
14
9
  let config = scanConfig.getScanConfig(argvMain);
15
- let scanResults = await startScan(config);
10
+ if (config.experimental) {
11
+ await processSca(config);
12
+ }
13
+ let scanResults = new ScanResultsModel(await startScan(config));
16
14
  if (scanResults) {
17
- formatScanOutput(scanResults?.projectOverview, scanResults?.scanResultsInstances);
15
+ formatScanOutput(scanResults);
18
16
  }
19
- if (config.save) {
20
- if (config.save.toLowerCase() === 'sarif') {
21
- const scanId = scanResults.scanDetail.id;
22
- const client = commonApi.getHttpClient(config);
23
- const rawResults = await client.getSpecificScanResultSarif(config, scanId);
24
- saveResults.writeResultsToFile(rawResults?.body);
25
- }
26
- else {
27
- console.log(i18n.__('scanNoFiletypeSpecifiedForSave'));
28
- }
17
+ if (config.save !== undefined) {
18
+ await saveScanFile(config, scanResults);
29
19
  }
30
20
  };
31
- const printHelpMessage = () => {
32
- console.log(scanUsageGuide);
33
- };
34
21
  module.exports = {
35
- processScan,
36
- printHelpMessage
22
+ processScan
37
23
  };
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ const autoDetection = require('../../../scan/autoDetection');
3
+ const { javaAnalysis } = require('../../../scaAnalysis/java');
4
+ const { commonSendSnapShot } = require('../../../scaAnalysis/common/treeUpload');
5
+ const { manualDetectAuditFilesAndLanguages } = require('../../../scan/autoDetection');
6
+ const { dealWithNoAppId } = require('../../audit/auditController');
7
+ const { supportedLanguages: { JAVA } } = require('../../../audit/languageAnalysisEngine/constants');
8
+ const processSca = async (config) => {
9
+ let filesFound;
10
+ if (config.projectPath) {
11
+ filesFound = await manualDetectAuditFilesAndLanguages(config.projectPath);
12
+ }
13
+ else {
14
+ filesFound = await autoDetection.autoDetectAuditFilesAndLanguages(config);
15
+ }
16
+ let messageToSend = undefined;
17
+ if (filesFound.length === 1) {
18
+ switch (Object.keys(filesFound[0])[0]) {
19
+ case JAVA:
20
+ messageToSend = await javaAnalysis(config, filesFound[0]);
21
+ config.language = JAVA;
22
+ break;
23
+ default:
24
+ console.log('language detected not supported');
25
+ return;
26
+ }
27
+ if (!config.applicationId) {
28
+ config.applicationId = await dealWithNoAppId(config);
29
+ }
30
+ console.log('processing dependencies');
31
+ const response = await commonSendSnapShot(messageToSend, config);
32
+ }
33
+ else {
34
+ if (filesFound.length === 0) {
35
+ console.log('no compatible dependency files detected. Continuing...');
36
+ }
37
+ else {
38
+ console.log('multiple language files detected, please use --project-path to specify a directory or the file where dependencies are declared');
39
+ }
40
+ }
41
+ };
42
+ module.exports = {
43
+ processSca
44
+ };
@@ -77,7 +77,9 @@ HTTPClient.prototype.getScanId = function getScanId(config, codeArtifactId) {
77
77
  options.url = url;
78
78
  options.body = {
79
79
  codeArtifactId: codeArtifactId,
80
- label: `Started by CLI tool at ${new Date().toString()}`
80
+ label: config.label
81
+ ? config.label
82
+ : `Started by CLI tool at ${new Date().toString()}`
81
83
  };
82
84
  return requestUtils.sendRequest({ method: 'post', options });
83
85
  };
@@ -97,6 +99,9 @@ HTTPClient.prototype.createProjectId = function createProjectId(config) {
97
99
  name: config.name,
98
100
  archived: 'false'
99
101
  };
102
+ if (config.language) {
103
+ options.body.language = config.language;
104
+ }
100
105
  options.url = createHarmonyProjectsUrl(config);
101
106
  return requestUtils.sendRequest({ method: 'post', options });
102
107
  };
@@ -140,28 +145,27 @@ HTTPClient.prototype.catalogueCommand = function catalogueCommand(config) {
140
145
  return requestUtils.sendRequest({ method: 'post', options });
141
146
  };
142
147
  HTTPClient.prototype.sendSnapshot = function sendSnapshot(requestBody, config) {
148
+ if (config.language.toUpperCase() === 'RUBY') {
149
+ }
143
150
  const options = _.cloneDeep(this.requestOptions);
144
151
  let url = createSnapshotURL(config);
145
152
  options.url = url;
146
153
  options.body = requestBody;
147
154
  return requestUtils.sendRequest({ method: 'post', options });
148
155
  };
149
- HTTPClient.prototype.getReport = function getReport(config) {
150
- const options = _.cloneDeep(this.requestOptions);
151
- let url = createReportUrl(config);
152
- options.url = url;
153
- return requestUtils.sendRequest({ method: 'get', options });
154
- };
155
- HTTPClient.prototype.getSpecificReport = function getSpecificReport(config, reportId) {
156
+ HTTPClient.prototype.getReportById = function getReportById(config, reportId) {
156
157
  const options = _.cloneDeep(this.requestOptions);
157
- let url = createSpecificReportUrl(config, reportId);
158
- options.url = url;
158
+ if (config.ignoreDev) {
159
+ options.url = createSpecificReportWithProdUrl(config, reportId);
160
+ }
161
+ else {
162
+ options.url = createSpecificReportUrl(config, reportId);
163
+ }
159
164
  return requestUtils.sendRequest({ method: 'get', options });
160
165
  };
161
- HTTPClient.prototype.getLibraryVulnerabilities = function getLibraryVulnerabilities(requestBody, config) {
166
+ HTTPClient.prototype.getLibraryVulnerabilities = function getLibraryVulnerabilities(config, requestBody) {
162
167
  const options = _.cloneDeep(this.requestOptions);
163
- let url = createLibraryVulnerabilitiesUrl(config);
164
- options.url = url;
168
+ options.url = createLibraryVulnerabilitiesUrl(config);
165
169
  options.body = requestBody;
166
170
  return requestUtils.sendRequest({ method: 'put', options });
167
171
  };
@@ -171,12 +175,6 @@ HTTPClient.prototype.getAppId = function getAppId(config) {
171
175
  options.url = url;
172
176
  return requestUtils.sendRequest({ method: 'get', options });
173
177
  };
174
- HTTPClient.prototype.getDependencyTree = function getReport(orgUuid, appId, reportId) {
175
- const options = _.cloneDeep(this.requestOptions);
176
- let url = createGetDependencyTree(options.uri, orgUuid, appId, reportId);
177
- options.url = url;
178
- return requestUtils.sendRequest({ method: 'get', options });
179
- };
180
178
  function getServerlessHost(config = {}) {
181
179
  const originalHost = config?.host || config?.get('host');
182
180
  const host = originalHost?.endsWith('/')
@@ -224,6 +222,11 @@ HTTPClient.prototype.checkLibrary = function checkLibrary(data) {
224
222
  options.body = data;
225
223
  return requestUtils.sendRequest({ method: 'post', options });
226
224
  };
225
+ HTTPClient.prototype.getSbom = function getSbom(config) {
226
+ const options = _.cloneDeep(this.requestOptions);
227
+ options.url = createSbomCycloneDXUrl(config);
228
+ return requestUtils.sendRequest({ method: 'get', options });
229
+ };
227
230
  const createGetScanIdURL = config => {
228
231
  return `${config.host}/Contrast/api/sast/v1/organizations/${config.organizationId}/projects/${config.projectId}/scans/`;
229
232
  };
@@ -263,18 +266,18 @@ const createAppNameUrl = config => {
263
266
  function createLibraryVulnerabilitiesUrl(config) {
264
267
  return `${config.host}/Contrast/api/ng/${config.organizationId}/libraries/artifactsByGroupNameVersion`;
265
268
  }
266
- function createReportUrl(config) {
267
- return `${config.host}/Contrast/api/ng/sca/organizations/${config.organizationId}/applications/${config.applicationId}/reports`;
268
- }
269
269
  function createSpecificReportUrl(config, reportId) {
270
- return `${config.host}/Contrast/api/ng/sca/organizations/${config.organizationId}/applications/${config.applicationId}/reports/${reportId}?nodesToInclude=PROD`;
270
+ return `${config.host}/Contrast/api/ng/sca/organizations/${config.organizationId}/applications/${config.applicationId}/reports/${reportId}`;
271
+ }
272
+ function createSpecificReportWithProdUrl(config, reportId) {
273
+ return createSpecificReportUrl(config, reportId).concat(`?nodesToInclude=PROD`);
271
274
  }
272
275
  function createDataUrl() {
273
276
  return `https://ardy.contrastsecurity.com/production`;
274
277
  }
275
- const createGetDependencyTree = (protocol, orgUuid, appId, reportId) => {
276
- return `${protocol}/Contrast/api/ng/sca/organizations/${orgUuid}/applications/${appId}/reports/${reportId}`;
277
- };
278
+ function createSbomCycloneDXUrl(config) {
279
+ return `${config.host}/Contrast/api/ng/${config.organizationId}/applications/${config.applicationId}/libraries/sbom/cyclonedx`;
280
+ }
278
281
  module.exports = HTTPClient;
279
282
  module.exports.pollForAuthUrl = pollForAuthUrl;
280
283
  module.exports.getServerlessHost = getServerlessHost;