@contrast/contrast 1.0.4 → 1.0.7

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 (115) hide show
  1. package/.prettierignore +0 -3
  2. package/dist/audit/autodetection/autoDetectLanguage.js +32 -0
  3. package/dist/audit/catalogueApplication/catalogueApplication.js +2 -11
  4. package/dist/audit/javaAnalysisEngine/parseMavenProjectFileContents.js +4 -2
  5. package/dist/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +2 -1
  6. package/dist/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +2 -1
  7. package/dist/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +2 -1
  8. package/dist/audit/languageAnalysisEngine/languageAnalysisFactory.js +6 -2
  9. package/dist/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +39 -1
  10. package/dist/audit/languageAnalysisEngine/report/commonReportingFunctions.js +69 -30
  11. package/dist/audit/languageAnalysisEngine/report/models/reportOutputModel.js +24 -0
  12. package/dist/audit/languageAnalysisEngine/report/models/reportSeverityModel.js +3 -1
  13. package/dist/audit/languageAnalysisEngine/report/models/severityCountModel.js +13 -0
  14. package/dist/audit/languageAnalysisEngine/report/reportingFeature.js +2 -2
  15. package/dist/audit/languageAnalysisEngine/report/utils/reportUtils.js +56 -45
  16. package/dist/audit/languageAnalysisEngine/sendSnapshot.js +65 -17
  17. package/dist/commands/audit/auditConfig.js +8 -2
  18. package/dist/commands/audit/auditController.js +9 -3
  19. package/dist/commands/audit/processAudit.js +1 -1
  20. package/dist/commands/scan/processScan.js +7 -4
  21. package/dist/commands/scan/sca/scaAnalysis.js +60 -0
  22. package/dist/common/HTTPClient.js +50 -16
  23. package/dist/common/errorHandling.js +11 -16
  24. package/dist/common/versionChecker.js +1 -1
  25. package/dist/constants/constants.js +24 -2
  26. package/dist/constants/locales.js +31 -36
  27. package/dist/constants.js +20 -0
  28. package/dist/lambda/analytics.js +11 -0
  29. package/dist/lambda/lambda.js +35 -4
  30. package/dist/lambda/types.js +13 -0
  31. package/dist/scaAnalysis/common/formatMessage.js +35 -0
  32. package/dist/scaAnalysis/common/treeUpload.js +29 -0
  33. package/dist/scaAnalysis/go/goAnalysis.js +17 -0
  34. package/dist/scaAnalysis/go/goParseDeps.js +158 -0
  35. package/dist/scaAnalysis/go/goReadDepFile.js +23 -0
  36. package/dist/scaAnalysis/java/analysis.js +105 -0
  37. package/dist/scaAnalysis/java/index.js +18 -0
  38. package/dist/scaAnalysis/java/javaBuildDepsParser.js +339 -0
  39. package/dist/scaAnalysis/python/analysis.js +41 -0
  40. package/dist/scaAnalysis/python/index.js +10 -0
  41. package/dist/scaAnalysis/ruby/analysis.js +226 -0
  42. package/dist/scaAnalysis/ruby/index.js +10 -0
  43. package/dist/scan/autoDetection.js +50 -1
  44. package/dist/scan/fileUtils.js +80 -1
  45. package/dist/scan/formatScanOutput.js +213 -0
  46. package/dist/scan/help.js +3 -1
  47. package/dist/scan/models/groupedResultsModel.js +2 -1
  48. package/dist/scan/models/scanResultsModel.js +3 -1
  49. package/dist/scan/populateProjectIdAndProjectName.js +2 -1
  50. package/dist/scan/scan.js +6 -99
  51. package/dist/scan/scanConfig.js +6 -1
  52. package/dist/scan/scanController.js +26 -7
  53. package/dist/scan/scanResults.js +20 -20
  54. package/dist/utils/commonApi.js +4 -1
  55. package/dist/utils/oraWrapper.js +5 -1
  56. package/package.json +12 -7
  57. package/src/audit/autodetection/autoDetectLanguage.ts +40 -0
  58. package/src/audit/catalogueApplication/catalogueApplication.js +3 -16
  59. package/src/audit/javaAnalysisEngine/parseMavenProjectFileContents.js +11 -8
  60. package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +2 -1
  61. package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +2 -1
  62. package/src/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +2 -1
  63. package/src/audit/languageAnalysisEngine/languageAnalysisFactory.js +17 -5
  64. package/src/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +76 -3
  65. package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.ts +122 -40
  66. package/src/audit/languageAnalysisEngine/report/models/reportLibraryModel.ts +3 -3
  67. package/src/audit/languageAnalysisEngine/report/models/reportListModel.ts +15 -11
  68. package/src/audit/languageAnalysisEngine/report/models/reportOutputModel.ts +29 -0
  69. package/src/audit/languageAnalysisEngine/report/models/reportSeverityModel.ts +12 -3
  70. package/src/audit/languageAnalysisEngine/report/models/severityCountModel.ts +16 -0
  71. package/src/audit/languageAnalysisEngine/report/reportingFeature.ts +3 -3
  72. package/src/audit/languageAnalysisEngine/report/utils/reportUtils.ts +87 -65
  73. package/src/audit/languageAnalysisEngine/sendSnapshot.js +78 -25
  74. package/src/commands/audit/auditConfig.ts +12 -3
  75. package/src/commands/audit/auditController.ts +9 -3
  76. package/src/commands/audit/processAudit.ts +4 -1
  77. package/src/commands/scan/processScan.js +10 -4
  78. package/src/commands/scan/sca/scaAnalysis.js +83 -0
  79. package/src/common/HTTPClient.js +65 -25
  80. package/src/common/errorHandling.ts +14 -22
  81. package/src/common/versionChecker.ts +1 -1
  82. package/src/constants/constants.js +24 -2
  83. package/src/constants/locales.js +33 -50
  84. package/src/constants.js +22 -0
  85. package/src/lambda/analytics.ts +9 -0
  86. package/src/lambda/arn.ts +2 -1
  87. package/src/lambda/lambda.ts +37 -17
  88. package/src/lambda/types.ts +35 -0
  89. package/src/lambda/utils.ts +2 -7
  90. package/src/scaAnalysis/common/formatMessage.js +38 -0
  91. package/src/scaAnalysis/common/treeUpload.js +30 -0
  92. package/src/scaAnalysis/go/goAnalysis.js +19 -0
  93. package/src/scaAnalysis/go/goParseDeps.js +203 -0
  94. package/src/scaAnalysis/go/goReadDepFile.js +32 -0
  95. package/src/scaAnalysis/java/analysis.js +142 -0
  96. package/src/scaAnalysis/java/index.js +21 -0
  97. package/src/scaAnalysis/java/javaBuildDepsParser.js +404 -0
  98. package/src/scaAnalysis/python/analysis.js +48 -0
  99. package/src/scaAnalysis/python/index.js +11 -0
  100. package/src/scaAnalysis/ruby/analysis.js +282 -0
  101. package/src/scaAnalysis/ruby/index.js +11 -0
  102. package/src/scan/autoDetection.js +58 -1
  103. package/src/scan/fileUtils.js +99 -1
  104. package/src/scan/formatScanOutput.ts +249 -0
  105. package/src/scan/help.js +3 -1
  106. package/src/scan/models/groupedResultsModel.ts +7 -5
  107. package/src/scan/models/resultContentModel.ts +2 -2
  108. package/src/scan/models/scanResultsModel.ts +5 -2
  109. package/src/scan/populateProjectIdAndProjectName.js +3 -1
  110. package/src/scan/scan.ts +8 -136
  111. package/src/scan/scanConfig.js +5 -1
  112. package/src/scan/scanController.js +30 -10
  113. package/src/scan/scanResults.js +31 -18
  114. package/src/utils/commonApi.js +4 -1
  115. package/src/utils/oraWrapper.js +6 -1
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  const i18n = require('i18n');
3
3
  const fileFinder = require('./fileUtils');
4
+ const languageResolver = require('../audit/languageAnalysisEngine/reduceIdentifiedLanguages');
5
+ const rootFile = require('../audit/languageAnalysisEngine/getProjectRootFilenames');
4
6
  const autoDetectFileAndLanguage = async (configToUse) => {
5
7
  const entries = await fileFinder.findFile();
6
8
  if (entries.length === 1) {
@@ -9,6 +11,10 @@ const autoDetectFileAndLanguage = async (configToUse) => {
9
11
  console.log(i18n.__('fileHasWhiteSpacesError'));
10
12
  process.exit(1);
11
13
  }
14
+ if (fileFinder.fileIsEmpty(entries[0])) {
15
+ console.log(i18n.__('scanFileIsEmpty'));
16
+ process.exit(1);
17
+ }
12
18
  configToUse.file = entries[0];
13
19
  if (configToUse.name === undefined) {
14
20
  configToUse.name = entries[0];
@@ -18,6 +24,31 @@ const autoDetectFileAndLanguage = async (configToUse) => {
18
24
  errorOnFileDetection(entries);
19
25
  }
20
26
  };
27
+ const autoDetectAuditFilesAndLanguages = async () => {
28
+ let languagesFound = [];
29
+ console.log(i18n.__('searchingAuditFileDirectory', process.cwd()));
30
+ await fileFinder.findFilesJava(languagesFound);
31
+ await fileFinder.findFilesJavascript(languagesFound);
32
+ await fileFinder.findFilesPython(languagesFound);
33
+ await fileFinder.findFilesGo(languagesFound);
34
+ await fileFinder.findFilesPhp(languagesFound);
35
+ await fileFinder.findFilesRuby(languagesFound);
36
+ if (languagesFound.length === 1) {
37
+ return languagesFound;
38
+ }
39
+ else {
40
+ console.log('found multiple languages, please specify one using --file to run SCA analysis');
41
+ }
42
+ };
43
+ const manualDetectAuditFilesAndLanguages = projectPath => {
44
+ let projectRootFilenames = rootFile.getProjectRootFilenames(projectPath);
45
+ let identifiedLanguages = languageResolver.deduceLanguageScaAnalysis(projectRootFilenames);
46
+ if (Object.keys(identifiedLanguages).length === 0) {
47
+ console.log(i18n.__('languageAnalysisNoLanguage', projectPath));
48
+ return [];
49
+ }
50
+ return [identifiedLanguages];
51
+ };
21
52
  const hasWhiteSpace = s => {
22
53
  const filename = s.split('/').pop();
23
54
  return filename.indexOf(' ') >= 0;
@@ -38,7 +69,25 @@ const errorOnFileDetection = entries => {
38
69
  }
39
70
  process.exit(1);
40
71
  };
72
+ const errorOnAuditFileDetection = entries => {
73
+ if (entries.length > 1) {
74
+ console.log(i18n.__('searchingDirectoryScan'));
75
+ for (let file in entries) {
76
+ console.log('-', entries[file]);
77
+ }
78
+ console.log('');
79
+ console.log(i18n.__('specifyFileAuditNotFound'));
80
+ }
81
+ else {
82
+ console.log(i18n.__('noFileFoundScan'));
83
+ console.log('');
84
+ console.log(i18n.__('specifyFileAuditNotFound'));
85
+ }
86
+ };
41
87
  module.exports = {
42
88
  autoDetectFileAndLanguage,
43
- errorOnFileDetection
89
+ errorOnFileDetection,
90
+ autoDetectAuditFilesAndLanguages,
91
+ errorOnAuditFileDetection,
92
+ manualDetectAuditFilesAndLanguages
44
93
  };
@@ -10,6 +10,72 @@ const findFile = async () => {
10
10
  onlyFiles: true
11
11
  });
12
12
  };
13
+ const findFilesJava = async (languagesFound) => {
14
+ const result = await fg(['**/pom.xml', '**/build.gradle', '**/build.gradle.kts'], {
15
+ dot: false,
16
+ deep: 1,
17
+ onlyFiles: true
18
+ });
19
+ if (result.length > 0) {
20
+ return languagesFound.push({ JAVA: result });
21
+ }
22
+ return languagesFound;
23
+ };
24
+ const findFilesJavascript = async (languagesFound) => {
25
+ const result = await fg(['**/package.json', '**/yarn.lock', '**/package.lock.json'], {
26
+ dot: false,
27
+ deep: 1,
28
+ onlyFiles: true
29
+ });
30
+ if (result.length > 0) {
31
+ return languagesFound.push({ JAVASCRIPT: result });
32
+ }
33
+ return languagesFound;
34
+ };
35
+ const findFilesPython = async (languagesFound) => {
36
+ const result = await fg(['**/Pipfile.lock', '**/Pipfile'], {
37
+ dot: false,
38
+ deep: 3,
39
+ onlyFiles: true
40
+ });
41
+ if (result.length > 0) {
42
+ return languagesFound.push({ PYTHON: result });
43
+ }
44
+ return languagesFound;
45
+ };
46
+ const findFilesGo = async (languagesFound) => {
47
+ const result = await fg(['**/go.mod'], {
48
+ dot: false,
49
+ deep: 3,
50
+ onlyFiles: true
51
+ });
52
+ if (result.length > 0) {
53
+ return languagesFound.push({ GO: result });
54
+ }
55
+ return languagesFound;
56
+ };
57
+ const findFilesRuby = async (languagesFound) => {
58
+ const result = await fg(['**/Gemfile', '**/Gemfile.lock'], {
59
+ dot: false,
60
+ deep: 3,
61
+ onlyFiles: true
62
+ });
63
+ if (result.length > 0) {
64
+ return languagesFound.push({ RUBY: result });
65
+ }
66
+ return languagesFound;
67
+ };
68
+ const findFilesPhp = async (languagesFound) => {
69
+ const result = await fg(['**/composer.json', '**/composer.lock'], {
70
+ dot: false,
71
+ deep: 3,
72
+ onlyFiles: true
73
+ });
74
+ if (result.length > 0) {
75
+ return languagesFound.push({ PHP: result });
76
+ }
77
+ return languagesFound;
78
+ };
13
79
  const checkFilePermissions = file => {
14
80
  let readableFile = false;
15
81
  try {
@@ -24,8 +90,21 @@ const checkFilePermissions = file => {
24
90
  const fileExists = path => {
25
91
  return fs.existsSync(path);
26
92
  };
93
+ const fileIsEmpty = path => {
94
+ if (fileExists(path) && checkFilePermissions(path)) {
95
+ return fs.readFileSync(path).length === 0;
96
+ }
97
+ return false;
98
+ };
27
99
  module.exports = {
28
100
  findFile,
29
101
  fileExists,
30
- checkFilePermissions
102
+ checkFilePermissions,
103
+ findFilesJava,
104
+ findFilesJavascript,
105
+ findFilesPython,
106
+ findFilesGo,
107
+ findFilesPhp,
108
+ findFilesRuby,
109
+ fileIsEmpty
31
110
  };
@@ -0,0 +1,213 @@
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.assignBySeverity = exports.stripTags = exports.getCodeFlowInfo = exports.getSourceLineNumber = exports.getLocationsSyncInfo = exports.editVulName = exports.getDefaultView = exports.formatLinks = exports.getProjectOverview = exports.formatScanOutput = void 0;
7
+ const i18n_1 = __importDefault(require("i18n"));
8
+ const chalk_1 = __importDefault(require("chalk"));
9
+ const groupedResultsModel_1 = require("./models/groupedResultsModel");
10
+ const lodash_1 = require("lodash");
11
+ const cli_table3_1 = __importDefault(require("cli-table3"));
12
+ const constants_1 = require("../constants/constants");
13
+ function formatScanOutput(scanResults) {
14
+ const { scanResultsInstances } = scanResults;
15
+ const projectOverview = getProjectOverview(scanResultsInstances);
16
+ if (scanResultsInstances.content.length === 0) {
17
+ console.log(i18n_1.default.__('scanNoVulnerabilitiesFound'));
18
+ console.log(i18n_1.default.__('scanNoVulnerabilitiesFoundSecureCode'));
19
+ console.log(i18n_1.default.__('scanNoVulnerabilitiesFoundGoodWork'));
20
+ }
21
+ else {
22
+ const message = projectOverview.critical || projectOverview.high
23
+ ? 'Here are your top priorities to fix'
24
+ : "No major issues, here's what we found";
25
+ console.log(chalk_1.default.bold(message));
26
+ console.log();
27
+ let defaultView = getDefaultView(scanResultsInstances.content);
28
+ let count = defaultView.length;
29
+ defaultView.forEach(entry => {
30
+ let table = new cli_table3_1.default({
31
+ chars: {
32
+ top: '',
33
+ 'top-mid': '',
34
+ 'top-left': '',
35
+ 'top-right': '',
36
+ bottom: '',
37
+ 'bottom-mid': '',
38
+ 'bottom-left': '',
39
+ 'bottom-right': '',
40
+ left: '',
41
+ 'left-mid': '',
42
+ mid: '',
43
+ 'mid-mid': '',
44
+ right: '',
45
+ 'right-mid': '',
46
+ middle: ' '
47
+ },
48
+ style: { 'padding-left': 0, 'padding-right': 0 },
49
+ colAligns: ['right'],
50
+ wordWrap: true,
51
+ colWidths: [12, 1, 100]
52
+ });
53
+ let learnRow = [];
54
+ let adviceRow = [];
55
+ const headerRow = [
56
+ chalk_1.default
57
+ .hex(entry.colour)
58
+ .bold(`CONTRAST-${count.toString().padStart(3, '0')}`),
59
+ chalk_1.default.hex(entry.colour).bold('-'),
60
+ chalk_1.default.hex(entry.colour).bold(`[${entry.severity}] ${entry.ruleId}`) +
61
+ entry.message
62
+ ];
63
+ const codePath = entry.codePath?.replace(/^@/, '');
64
+ const codeRow = [
65
+ chalk_1.default.hex('#F6F5F5').bold(`Code`),
66
+ chalk_1.default.hex('#F6F5F5').bold(`:`),
67
+ chalk_1.default.hex('#F6F5F5').bold(`${codePath}`)
68
+ ];
69
+ const issueRow = [chalk_1.default.bold(`Issue`), chalk_1.default.bold(`:`), `${entry.issue}`];
70
+ table.push(headerRow, codeRow, issueRow);
71
+ if (entry?.advice) {
72
+ adviceRow = [
73
+ chalk_1.default.bold('Advice'),
74
+ chalk_1.default.bold(`:`),
75
+ stripTags(entry.advice)
76
+ ];
77
+ table.push(adviceRow);
78
+ }
79
+ if (entry?.learn && entry?.learn.length > 0) {
80
+ learnRow = [
81
+ chalk_1.default.bold('Learn'),
82
+ chalk_1.default.bold(`:`),
83
+ chalk_1.default.hex('#97f7f7').bold.underline(entry.learn[0])
84
+ ];
85
+ table.push(learnRow);
86
+ }
87
+ count--;
88
+ console.log(table.toString());
89
+ console.log();
90
+ });
91
+ }
92
+ printVulnInfo(projectOverview);
93
+ }
94
+ exports.formatScanOutput = formatScanOutput;
95
+ function printVulnInfo(projectOverview) {
96
+ const totalVulnerabilities = projectOverview.total;
97
+ const vulMessage = totalVulnerabilities === 1 ? `vulnerability` : `vulnerabilities`;
98
+ console.log(chalk_1.default.bold(`Found ${totalVulnerabilities} ${vulMessage}`));
99
+ console.log(i18n_1.default.__('foundDetailedVulnerabilities', String(projectOverview.critical), String(projectOverview.high), String(projectOverview.medium), String(projectOverview.low), String(projectOverview.note)));
100
+ }
101
+ function getProjectOverview(scanResultsInstances) {
102
+ const acc = {
103
+ critical: 0,
104
+ high: 0,
105
+ medium: 0,
106
+ low: 0,
107
+ note: 0,
108
+ total: 0
109
+ };
110
+ if (scanResultsInstances?.content &&
111
+ scanResultsInstances.content.length > 0) {
112
+ scanResultsInstances.content.forEach((i) => {
113
+ acc[i.severity.toLowerCase()] += 1;
114
+ acc.total += 1;
115
+ return acc;
116
+ });
117
+ }
118
+ return acc;
119
+ }
120
+ exports.getProjectOverview = getProjectOverview;
121
+ function formatLinks(objName, entry) {
122
+ const line = chalk_1.default.bold(objName + ' : ');
123
+ if (entry.length === 1) {
124
+ console.log(line + chalk_1.default.hex('#97DCF7').bold.underline(entry[0]));
125
+ }
126
+ else {
127
+ console.log(line);
128
+ entry.forEach(link => {
129
+ console.log(chalk_1.default.hex('#97DCF7').bold.underline(link));
130
+ });
131
+ }
132
+ }
133
+ exports.formatLinks = formatLinks;
134
+ function getDefaultView(content) {
135
+ const groupTypeResults = [];
136
+ content.forEach(resultEntry => {
137
+ const groupResultsObj = new groupedResultsModel_1.GroupedResultsModel(resultEntry.ruleId);
138
+ groupResultsObj.severity = resultEntry.severity;
139
+ groupResultsObj.ruleId = resultEntry.ruleId;
140
+ groupResultsObj.issue = stripTags(resultEntry.issue);
141
+ groupResultsObj.advice = resultEntry.advice;
142
+ groupResultsObj.learn = resultEntry.learn;
143
+ groupResultsObj.message = resultEntry.message?.text
144
+ ? editVulName(resultEntry.message.text) +
145
+ ':' +
146
+ getSourceLineNumber(resultEntry)
147
+ : '';
148
+ groupResultsObj.codePath = getLocationsSyncInfo(resultEntry);
149
+ groupTypeResults.push(groupResultsObj);
150
+ assignBySeverity(resultEntry, groupResultsObj);
151
+ });
152
+ return (0, lodash_1.sortBy)(groupTypeResults, ['priority']).reverse();
153
+ }
154
+ exports.getDefaultView = getDefaultView;
155
+ function editVulName(message) {
156
+ return message.substring(message.indexOf(' in '));
157
+ }
158
+ exports.editVulName = editVulName;
159
+ function getLocationsSyncInfo(resultEntry) {
160
+ const locationsMessage = resultEntry.locations[0]?.physicalLocation?.artifactLocation?.uri || '';
161
+ const locationsLineNumber = resultEntry.locations[0]?.physicalLocation?.region?.startLine || '';
162
+ if (!locationsLineNumber) {
163
+ return '@' + locationsMessage;
164
+ }
165
+ return '@' + locationsMessage + ':' + locationsLineNumber;
166
+ }
167
+ exports.getLocationsSyncInfo = getLocationsSyncInfo;
168
+ function getSourceLineNumber(resultEntry) {
169
+ const locationsLineNumber = resultEntry.locations[0]?.physicalLocation?.region?.startLine || '';
170
+ let codeFlowLineNumber = getCodeFlowInfo(resultEntry);
171
+ return codeFlowLineNumber ? codeFlowLineNumber : locationsLineNumber;
172
+ }
173
+ exports.getSourceLineNumber = getSourceLineNumber;
174
+ function getCodeFlowInfo(resultEntry) {
175
+ let result;
176
+ resultEntry.codeFlows[0]?.threadFlows.forEach((i) => {
177
+ return (result = i.locations.find((locations) => locations.importance === 'essential'));
178
+ });
179
+ return result?.location?.physicalLocation?.region?.startLine;
180
+ }
181
+ exports.getCodeFlowInfo = getCodeFlowInfo;
182
+ function stripTags(oldString) {
183
+ return oldString.replace(/\n/g, ' ').replace(/\s+/g, ' ').trim();
184
+ }
185
+ exports.stripTags = stripTags;
186
+ function assignBySeverity(entry, assignedObj) {
187
+ if (entry.severity.toUpperCase() === 'CRITICAL') {
188
+ assignedObj.priority = 1;
189
+ assignedObj.colour = constants_1.CRITICAL_COLOUR;
190
+ return assignedObj;
191
+ }
192
+ else if (entry.severity.toUpperCase() === 'HIGH') {
193
+ assignedObj.priority = 2;
194
+ assignedObj.colour = constants_1.HIGH_COLOUR;
195
+ return assignedObj;
196
+ }
197
+ else if (entry.severity.toUpperCase() === 'MEDIUM') {
198
+ assignedObj.priority = 3;
199
+ assignedObj.colour = constants_1.MEDIUM_COLOUR;
200
+ return assignedObj;
201
+ }
202
+ else if (entry.severity.toUpperCase() === 'LOW') {
203
+ assignedObj.priority = 4;
204
+ assignedObj.colour = constants_1.LOW_COLOUR;
205
+ return assignedObj;
206
+ }
207
+ else if (entry.severity.toUpperCase() === 'NOTE') {
208
+ assignedObj.priority = 5;
209
+ assignedObj.colour = constants_1.NOTE_COLOUR;
210
+ return assignedObj;
211
+ }
212
+ }
213
+ exports.assignBySeverity = assignBySeverity;
package/dist/scan/help.js CHANGED
@@ -30,7 +30,9 @@ const scanUsageGuide = commandLineUsage([
30
30
  'ff',
31
31
  'ignore-cert-errors',
32
32
  'verbose',
33
- 'debug'
33
+ 'debug',
34
+ 'experimental',
35
+ 'application-name'
34
36
  ]
35
37
  },
36
38
  {
@@ -4,7 +4,8 @@ exports.GroupedResultsModel = void 0;
4
4
  class GroupedResultsModel {
5
5
  constructor(ruleId) {
6
6
  this.ruleId = ruleId;
7
- this.lineInfoSet = new Set;
7
+ this.colour = '#999999';
8
+ this.codePathSet = new Set();
8
9
  }
9
10
  }
10
11
  exports.GroupedResultsModel = GroupedResultsModel;
@@ -5,7 +5,9 @@ class ScanResultsModel {
5
5
  constructor(scan) {
6
6
  this.projectOverview = scan.projectOverview;
7
7
  this.scanDetail = scan.scanDetail;
8
- this.scanResultsInstances = scan.scanResultsInstances;
8
+ this.scanResultsInstances =
9
+ scan.scanResultsInstances;
10
+ this.newProject = scan.newProject;
9
11
  }
10
12
  }
11
13
  exports.ScanResultsModel = ScanResultsModel;
@@ -8,8 +8,9 @@ const populateProjectId = async (config) => {
8
8
  proj = await getExistingProjectIdByName(config, client).then(res => {
9
9
  return res;
10
10
  });
11
+ return { projectId: proj, isNewProject: false };
11
12
  }
12
- return proj;
13
+ return { projectId: proj, isNewProject: true };
13
14
  };
14
15
  const createProjectId = async (config, client) => {
15
16
  return client
package/dist/scan/scan.js CHANGED
@@ -3,13 +3,11 @@ 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.stripMustacheTags = exports.getMessage = exports.getGroups = exports.formatLinks = exports.formatScanOutput = exports.sendScan = exports.isFileAllowed = exports.allowedFileTypes = void 0;
6
+ exports.sendScan = exports.isFileAllowed = exports.allowedFileTypes = void 0;
7
7
  const commonApi_js_1 = __importDefault(require("../utils/commonApi.js"));
8
8
  const fileUtils_1 = __importDefault(require("../scan/fileUtils"));
9
9
  const i18n_1 = __importDefault(require("i18n"));
10
10
  const oraWrapper_1 = __importDefault(require("../utils/oraWrapper"));
11
- const chalk_1 = __importDefault(require("chalk"));
12
- const groupedResultsModel_1 = require("./models/groupedResultsModel");
13
11
  exports.allowedFileTypes = ['.jar', '.war', '.js', '.zip', '.exe'];
14
12
  const isFileAllowed = (scanOption) => {
15
13
  let valid = false;
@@ -43,114 +41,23 @@ const sendScan = async (config) => {
43
41
  }
44
42
  else {
45
43
  if (config.debug) {
46
- console.log(res.statusCode);
47
44
  console.log(config);
45
+ oraWrapper_1.default.failSpinner(startUploadSpinner, i18n_1.default.__('uploadingScanFail'));
46
+ console.log(i18n_1.default.__('genericServiceError', res.statusCode));
48
47
  }
49
- oraWrapper_1.default.failSpinner(startUploadSpinner, i18n_1.default.__('uploadingScanFail'));
50
48
  if (res.statusCode === 403) {
51
49
  console.log(i18n_1.default.__('permissionsError'));
52
50
  process.exit(1);
53
51
  }
54
- console.log(i18n_1.default.__('genericServiceError', res.statusCode));
52
+ oraWrapper_1.default.stopSpinner(startUploadSpinner);
53
+ console.log('Contrast Scan Finished');
55
54
  process.exit(1);
56
55
  }
57
56
  })
58
57
  .catch(err => {
58
+ oraWrapper_1.default.stopSpinner(startUploadSpinner);
59
59
  console.log(err);
60
60
  });
61
61
  }
62
62
  };
63
63
  exports.sendScan = sendScan;
64
- function formatScanOutput(scanResults) {
65
- const { projectOverview, scanResultsInstances } = scanResults;
66
- if (scanResultsInstances.content.length === 0) {
67
- console.log(i18n_1.default.__('scanNoVulnerabilitiesFound'));
68
- }
69
- else {
70
- const message = projectOverview.critical || projectOverview.high
71
- ? 'Here are your top priorities to fix'
72
- : "No major issues, here's what we found";
73
- console.log(chalk_1.default.bold(message));
74
- console.log();
75
- const groups = getGroups(scanResultsInstances.content);
76
- groups.forEach(entry => {
77
- console.log(chalk_1.default.bold(`[ ${entry.severity} ] | ${entry.ruleId} (${entry.lineInfoSet.size}) - ` +
78
- `${entry.message}`));
79
- let count = 1;
80
- entry.lineInfoSet.forEach(lineInfo => {
81
- console.log(`\t ${count}. ${lineInfo}`);
82
- count++;
83
- });
84
- if (entry?.issue) {
85
- console.log(chalk_1.default.bold('Issue' + ': ') + entry.issue);
86
- }
87
- if (entry?.advice) {
88
- console.log(chalk_1.default.bold('Advice' + ': ') + entry.advice);
89
- }
90
- if (entry?.learn && entry?.learn.length > 0) {
91
- formatLinks('Learn', entry.learn);
92
- }
93
- console.log();
94
- });
95
- printVulnInfo(projectOverview);
96
- }
97
- }
98
- exports.formatScanOutput = formatScanOutput;
99
- function printVulnInfo(projectOverview) {
100
- const totalVulnerabilities = getTotalVulns(projectOverview);
101
- const vulMessage = totalVulnerabilities === 1 ? `vulnerability` : `vulnerabilities`;
102
- console.log(chalk_1.default.bold(`Found ${totalVulnerabilities} ${vulMessage}`));
103
- console.log(i18n_1.default.__('foundDetailedVulnerabilities', String(projectOverview.critical), String(projectOverview.high), String(projectOverview.medium), String(projectOverview.low), String(projectOverview.note)));
104
- }
105
- function getTotalVulns(projectOverview) {
106
- return (projectOverview.critical +
107
- projectOverview.high +
108
- projectOverview.medium +
109
- projectOverview.low +
110
- projectOverview.note);
111
- }
112
- function formatLinks(objName, entry) {
113
- console.log(chalk_1.default.bold(objName + ':'));
114
- entry.forEach(link => {
115
- console.log(link);
116
- });
117
- }
118
- exports.formatLinks = formatLinks;
119
- function getGroups(content) {
120
- const groupTypeSet = new Set(content.map(({ ruleId }) => ruleId));
121
- const groupTypeResults = [];
122
- groupTypeSet.forEach(groupName => {
123
- const groupResultsObj = new groupedResultsModel_1.GroupedResultsModel(groupName);
124
- content.forEach(resultEntry => {
125
- if (resultEntry.ruleId === groupName) {
126
- groupResultsObj.severity = resultEntry.severity;
127
- groupResultsObj.issue = stripMustacheTags(resultEntry.issue);
128
- groupResultsObj.advice = resultEntry.advice;
129
- groupResultsObj.learn = resultEntry.learn;
130
- groupResultsObj.message = resultEntry.message?.text;
131
- groupResultsObj.lineInfoSet.add(getMessage(resultEntry.locations));
132
- }
133
- });
134
- groupTypeResults.push(groupResultsObj);
135
- });
136
- return groupTypeResults;
137
- }
138
- exports.getGroups = getGroups;
139
- function getMessage(locations) {
140
- const message = locations[0]?.physicalLocation?.artifactLocation?.uri || '';
141
- const lineNumber = locations[0]?.physicalLocation?.region?.startLine || '';
142
- if (!lineNumber) {
143
- return '@' + message;
144
- }
145
- return '@' + message + ':' + lineNumber;
146
- }
147
- exports.getMessage = getMessage;
148
- function stripMustacheTags(oldString) {
149
- return oldString
150
- .replace(/\n/g, ' ')
151
- .replace(/{{.*?}}/g, '\n')
152
- .replace(/\$\$LINK_DELIM\$\$/g, '\n')
153
- .replace(/\s+/g, ' ')
154
- .trim();
155
- }
156
- exports.stripMustacheTags = stripMustacheTags;
@@ -21,10 +21,15 @@ const getScanConfig = argv => {
21
21
  process.exit(1);
22
22
  }
23
23
  }
24
+ let projectNameSource;
24
25
  if (!scanParams.name && scanParams.file) {
25
26
  scanParams.name = getFileName(scanParams.file);
27
+ projectNameSource = 'AUTO';
26
28
  }
27
- return { ...paramsAuth, ...scanParams };
29
+ else {
30
+ projectNameSource = 'USER';
31
+ }
32
+ return { ...paramsAuth, ...scanParams, projectNameSource };
28
33
  };
29
34
  const getFileName = file => {
30
35
  return file.split(path.sep).pop();
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  const i18n = require('i18n');
3
- const { returnOra, startSpinner, succeedSpinner } = require('../utils/oraWrapper');
3
+ const { returnOra, startSpinner, succeedSpinner, stopSpinner } = require('../utils/oraWrapper');
4
4
  const populateProjectIdAndProjectName = require('./populateProjectIdAndProjectName');
5
5
  const scan = require('./scan');
6
6
  const scanResults = require('./scanResults');
@@ -24,6 +24,10 @@ const fileAndLanguageLogic = async (configToUse) => {
24
24
  console.log(i18n.__('fileNotExist'));
25
25
  process.exit(1);
26
26
  }
27
+ if (fileFunctions.fileIsEmpty(configToUse.file)) {
28
+ console.log(i18n.__('scanFileIsEmpty'));
29
+ process.exit(1);
30
+ }
27
31
  return configToUse;
28
32
  }
29
33
  else {
@@ -35,21 +39,36 @@ const fileAndLanguageLogic = async (configToUse) => {
35
39
  const startScan = async (configToUse) => {
36
40
  const startTime = performance.now();
37
41
  await fileAndLanguageLogic(configToUse);
42
+ let newProject;
38
43
  if (!configToUse.projectId) {
39
- configToUse.projectId = await populateProjectIdAndProjectName.populateProjectId(configToUse);
44
+ const { projectId, isNewProject } = await populateProjectIdAndProjectName.populateProjectId(configToUse);
45
+ configToUse.projectId = projectId;
46
+ newProject = isNewProject;
47
+ }
48
+ else {
49
+ newProject = false;
40
50
  }
41
51
  const codeArtifactId = await scan.sendScan(configToUse);
42
52
  if (!configToUse.ff) {
43
53
  const startScanSpinner = returnOra('🚀 Contrast Scan started');
44
54
  startSpinner(startScanSpinner);
45
- const scanDetail = await scanResults.returnScanResults(configToUse, codeArtifactId, getTimeout(configToUse), startScanSpinner);
55
+ const scanDetail = await scanResults.returnScanResults(configToUse, codeArtifactId, newProject, getTimeout(configToUse), startScanSpinner);
46
56
  const scanResultsInstances = await scanResults.returnScanResultsInstances(configToUse, scanDetail.id);
47
57
  const endTime = performance.now();
48
58
  const scanDurationMs = endTime - startTime;
49
- succeedSpinner(startScanSpinner, 'Contrast Scan complete');
50
- console.log(`----- Scan completed in ${(scanDurationMs / 1000).toFixed(2)}s -----`);
51
- const projectOverview = await scanResults.returnScanProjectById(configToUse);
52
- return { projectOverview, scanDetail, scanResultsInstances };
59
+ if (scanResultsInstances.statusCode !== 200) {
60
+ stopSpinner(startScanSpinner);
61
+ console.log('Result Service is unavailable, please try again later');
62
+ process.exit(1);
63
+ }
64
+ else {
65
+ succeedSpinner(startScanSpinner, 'Contrast Scan complete');
66
+ console.log(`----- Scan completed in ${(scanDurationMs / 1000).toFixed(2)}s -----`);
67
+ return {
68
+ scanDetail,
69
+ scanResultsInstances: scanResultsInstances.body
70
+ };
71
+ }
53
72
  }
54
73
  };
55
74
  module.exports = {