@contrast/contrast 1.0.3 → 1.0.6

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