@contrast/contrast 1.0.3 → 1.0.4

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 (62) hide show
  1. package/.prettierignore +1 -0
  2. package/README.md +20 -14
  3. package/dist/audit/languageAnalysisEngine/{langugageAnalysisFactory.js → languageAnalysisFactory.js} +2 -12
  4. package/dist/audit/languageAnalysisEngine/report/commonReportingFunctions.js +62 -234
  5. package/dist/audit/languageAnalysisEngine/report/models/reportLibraryModel.js +19 -0
  6. package/dist/audit/languageAnalysisEngine/report/models/reportListModel.js +24 -0
  7. package/dist/audit/languageAnalysisEngine/report/models/reportSeverityModel.js +10 -0
  8. package/dist/audit/languageAnalysisEngine/report/reportingFeature.js +24 -129
  9. package/dist/audit/languageAnalysisEngine/report/utils/reportUtils.js +85 -0
  10. package/dist/audit/languageAnalysisEngine/sendSnapshot.js +3 -1
  11. package/dist/commands/audit/auditController.js +6 -3
  12. package/dist/commands/scan/processScan.js +4 -3
  13. package/dist/common/HTTPClient.js +19 -26
  14. package/dist/common/versionChecker.js +14 -12
  15. package/dist/constants/constants.js +1 -1
  16. package/dist/constants/lambda.js +3 -1
  17. package/dist/constants/locales.js +17 -10
  18. package/dist/constants.js +5 -1
  19. package/dist/index.js +2 -2
  20. package/dist/lambda/help.js +22 -14
  21. package/dist/lambda/lambda.js +6 -0
  22. package/dist/scan/models/groupedResultsModel.js +10 -0
  23. package/dist/scan/models/resultContentModel.js +2 -0
  24. package/dist/scan/models/scanResultsModel.js +11 -0
  25. package/dist/scan/scan.js +90 -95
  26. package/dist/scan/scanConfig.js +1 -1
  27. package/dist/utils/getConfig.js +3 -0
  28. package/package.json +2 -2
  29. package/src/audit/languageAnalysisEngine/{langugageAnalysisFactory.js → languageAnalysisFactory.js} +2 -16
  30. package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.ts +127 -0
  31. package/src/audit/languageAnalysisEngine/report/models/reportLibraryModel.ts +30 -0
  32. package/src/audit/languageAnalysisEngine/report/models/reportListModel.ts +32 -0
  33. package/src/audit/languageAnalysisEngine/report/models/reportSeverityModel.ts +9 -0
  34. package/src/audit/languageAnalysisEngine/report/reportingFeature.ts +56 -0
  35. package/src/audit/languageAnalysisEngine/report/utils/reportUtils.ts +110 -0
  36. package/src/audit/languageAnalysisEngine/sendSnapshot.js +3 -1
  37. package/src/commands/audit/auditController.ts +12 -3
  38. package/src/commands/scan/processScan.js +4 -6
  39. package/src/common/HTTPClient.js +31 -38
  40. package/src/common/errorHandling.ts +0 -1
  41. package/src/common/versionChecker.ts +24 -22
  42. package/src/constants/constants.js +1 -1
  43. package/src/constants/lambda.js +3 -1
  44. package/src/constants/locales.js +20 -10
  45. package/src/constants.js +7 -1
  46. package/src/index.ts +2 -3
  47. package/src/lambda/help.ts +22 -14
  48. package/src/lambda/lambda.ts +8 -0
  49. package/src/scan/models/groupedResultsModel.ts +18 -0
  50. package/src/scan/models/resultContentModel.ts +86 -0
  51. package/src/scan/models/scanResultsModel.ts +52 -0
  52. package/src/scan/scan.ts +192 -0
  53. package/src/scan/scanConfig.js +1 -1
  54. package/src/scan/scanController.js +2 -0
  55. package/src/utils/getConfig.ts +10 -0
  56. package/dist/audit/languageAnalysisEngine/report/checkIgnoreDevDep.js +0 -17
  57. package/dist/audit/languageAnalysisEngine/report/newReportingFeature.js +0 -81
  58. package/src/audit/languageAnalysisEngine/report/checkIgnoreDevDep.js +0 -27
  59. package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.js +0 -303
  60. package/src/audit/languageAnalysisEngine/report/newReportingFeature.js +0 -124
  61. package/src/audit/languageAnalysisEngine/report/reportingFeature.js +0 -190
  62. package/src/scan/scan.js +0 -195
@@ -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;
@@ -24,7 +24,9 @@ const newSendSnapShot = async (analysis, applicationId) => {
24
24
  .sendSnapshot(requestBody, analysis.config)
25
25
  .then(res => {
26
26
  if (res.statusCode === 201) {
27
- displaySnapshotSuccessMessage(analysis.config);
27
+ if (analysis.config.host !== 'https://ce.contrastsecurity.com/') {
28
+ displaySnapshotSuccessMessage(analysis.config);
29
+ }
28
30
  return res.body;
29
31
  }
30
32
  else {
@@ -7,7 +7,7 @@ exports.startAudit = 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
11
  const dealWithNoAppId = async (config) => {
12
12
  let appID;
13
13
  try {
@@ -17,9 +17,12 @@ const dealWithNoAppId = async (config) => {
17
17
  }
18
18
  }
19
19
  catch (e) {
20
- console.log(e);
20
+ if (e.toString().includes('tunneling socket could not be established')) {
21
+ console.log(e.message);
22
+ console.log('There seems to be an issue with your proxy, please check and try again');
23
+ }
24
+ process.exit(1);
21
25
  }
22
- console.log(appID);
23
26
  return appID;
24
27
  };
25
28
  const startAudit = async (config) => {
@@ -1,14 +1,15 @@
1
1
  "use strict";
2
2
  const { startScan } = require('../../scan/scanController');
3
- const { formatScanOutput } = require('../../scan/scan');
4
3
  const { scanUsageGuide } = require('../../scan/help');
5
4
  const scanConfig = require('../../scan/scanConfig');
6
5
  const { saveScanFile } = require('../../utils/saveFile');
6
+ const { ScanResultsModel } = require('../../scan/models/scanResultsModel');
7
+ const { formatScanOutput } = require('../../scan/scan');
7
8
  const processScan = async (argvMain) => {
8
9
  let config = scanConfig.getScanConfig(argvMain);
9
- let scanResults = await startScan(config);
10
+ let scanResults = new ScanResultsModel(await startScan(config));
10
11
  if (scanResults) {
11
- formatScanOutput(scanResults?.projectOverview, scanResults?.scanResultsInstances);
12
+ formatScanOutput(scanResults);
12
13
  }
13
14
  if (config.save !== undefined) {
14
15
  await saveScanFile(config, scanResults);
@@ -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
  };
@@ -143,28 +145,28 @@ HTTPClient.prototype.catalogueCommand = function catalogueCommand(config) {
143
145
  return requestUtils.sendRequest({ method: 'post', options });
144
146
  };
145
147
  HTTPClient.prototype.sendSnapshot = function sendSnapshot(requestBody, config) {
148
+ if (config.language.toUpperCase() === 'RUBY') {
149
+ console.log('sendSnapshot requestBody', requestBody.snapshot.ruby);
150
+ }
146
151
  const options = _.cloneDeep(this.requestOptions);
147
152
  let url = createSnapshotURL(config);
148
153
  options.url = url;
149
154
  options.body = requestBody;
150
155
  return requestUtils.sendRequest({ method: 'post', options });
151
156
  };
152
- HTTPClient.prototype.getReport = function getReport(config) {
153
- const options = _.cloneDeep(this.requestOptions);
154
- let url = createReportUrl(config);
155
- options.url = url;
156
- return requestUtils.sendRequest({ method: 'get', options });
157
- };
158
- HTTPClient.prototype.getSpecificReport = function getSpecificReport(config, reportId) {
157
+ HTTPClient.prototype.getReportById = function getReportById(config, reportId) {
159
158
  const options = _.cloneDeep(this.requestOptions);
160
- let url = createSpecificReportUrl(config, reportId);
161
- options.url = url;
159
+ if (config.ignoreDev) {
160
+ options.url = createSpecificReportWithProdUrl(config, reportId);
161
+ }
162
+ else {
163
+ options.url = createSpecificReportUrl(config, reportId);
164
+ }
162
165
  return requestUtils.sendRequest({ method: 'get', options });
163
166
  };
164
- HTTPClient.prototype.getLibraryVulnerabilities = function getLibraryVulnerabilities(requestBody, config) {
167
+ HTTPClient.prototype.getLibraryVulnerabilities = function getLibraryVulnerabilities(config, requestBody) {
165
168
  const options = _.cloneDeep(this.requestOptions);
166
- let url = createLibraryVulnerabilitiesUrl(config);
167
- options.url = url;
169
+ options.url = createLibraryVulnerabilitiesUrl(config);
168
170
  options.body = requestBody;
169
171
  return requestUtils.sendRequest({ method: 'put', options });
170
172
  };
@@ -174,12 +176,6 @@ HTTPClient.prototype.getAppId = function getAppId(config) {
174
176
  options.url = url;
175
177
  return requestUtils.sendRequest({ method: 'get', options });
176
178
  };
177
- HTTPClient.prototype.getDependencyTree = function getReport(orgUuid, appId, reportId) {
178
- const options = _.cloneDeep(this.requestOptions);
179
- let url = createGetDependencyTree(options.uri, orgUuid, appId, reportId);
180
- options.url = url;
181
- return requestUtils.sendRequest({ method: 'get', options });
182
- };
183
179
  function getServerlessHost(config = {}) {
184
180
  const originalHost = config?.host || config?.get('host');
185
181
  const host = originalHost?.endsWith('/')
@@ -271,18 +267,15 @@ const createAppNameUrl = config => {
271
267
  function createLibraryVulnerabilitiesUrl(config) {
272
268
  return `${config.host}/Contrast/api/ng/${config.organizationId}/libraries/artifactsByGroupNameVersion`;
273
269
  }
274
- function createReportUrl(config) {
275
- return `${config.host}/Contrast/api/ng/sca/organizations/${config.organizationId}/applications/${config.applicationId}/reports`;
276
- }
277
270
  function createSpecificReportUrl(config, reportId) {
278
- return `${config.host}/Contrast/api/ng/sca/organizations/${config.organizationId}/applications/${config.applicationId}/reports/${reportId}?nodesToInclude=PROD`;
271
+ return `${config.host}/Contrast/api/ng/sca/organizations/${config.organizationId}/applications/${config.applicationId}/reports/${reportId}`;
272
+ }
273
+ function createSpecificReportWithProdUrl(config, reportId) {
274
+ return createSpecificReportUrl(config, reportId).concat(`?nodesToInclude=PROD`);
279
275
  }
280
276
  function createDataUrl() {
281
277
  return `https://ardy.contrastsecurity.com/production`;
282
278
  }
283
- const createGetDependencyTree = (protocol, orgUuid, appId, reportId) => {
284
- return `${protocol}/Contrast/api/ng/sca/organizations/${orgUuid}/applications/${appId}/reports/${reportId}`;
285
- };
286
279
  function createSbomCycloneDXUrl(config) {
287
280
  return `${config.host}/Contrast/api/ng/${config.organizationId}/applications/${config.applicationId}/libraries/sbom/cyclonedx`;
288
281
  }
@@ -9,18 +9,20 @@ const constants_1 = require("../constants/constants");
9
9
  const boxen_1 = __importDefault(require("boxen"));
10
10
  const chalk_1 = __importDefault(require("chalk"));
11
11
  const semver_1 = __importDefault(require("semver"));
12
- async function findLatestCLIVersion() {
13
- const latestCLIVersion = await (0, latest_version_1.default)('@contrast/contrast');
14
- if (semver_1.default.lt(constants_1.APP_VERSION, latestCLIVersion)) {
15
- const updateAvailableMessage = `Update available ${chalk_1.default.yellow(constants_1.APP_VERSION)} → ${chalk_1.default.green(latestCLIVersion)}`;
16
- const npmUpdateAvailableCommand = `Run ${chalk_1.default.cyan('npm i @contrast/contrast -g')} to update via npm`;
17
- const homebrewUpdateAvailableCommand = `Run ${chalk_1.default.cyan('brew install contrastsecurity/tap/contrast')} to update via brew`;
18
- console.log((0, boxen_1.default)(`${updateAvailableMessage}\n${npmUpdateAvailableCommand}\n\n${homebrewUpdateAvailableCommand}`, {
19
- titleAlignment: 'center',
20
- margin: 1,
21
- padding: 1,
22
- align: 'center'
23
- }));
12
+ async function findLatestCLIVersion(updateMessageHidden) {
13
+ if (!updateMessageHidden) {
14
+ const latestCLIVersion = await (0, latest_version_1.default)('@contrast/contrast');
15
+ if (semver_1.default.lt(constants_1.APP_VERSION, latestCLIVersion)) {
16
+ const updateAvailableMessage = `Update available ${chalk_1.default.yellow(constants_1.APP_VERSION)} ${chalk_1.default.green(latestCLIVersion)}`;
17
+ const npmUpdateAvailableCommand = `Run ${chalk_1.default.cyan('npm i @contrast/contrast -g')} to update via npm`;
18
+ const homebrewUpdateAvailableCommand = `Run ${chalk_1.default.cyan('brew install contrastsecurity/tap/contrast')} to update via brew`;
19
+ console.log((0, boxen_1.default)(`${updateAvailableMessage}\n${npmUpdateAvailableCommand}\n\n${homebrewUpdateAvailableCommand}`, {
20
+ titleAlignment: 'center',
21
+ margin: 1,
22
+ padding: 1,
23
+ align: 'center'
24
+ }));
25
+ }
24
26
  }
25
27
  }
26
28
  exports.findLatestCLIVersion = findLatestCLIVersion;
@@ -12,7 +12,7 @@ const MEDIUM = 'MEDIUM';
12
12
  const HIGH = 'HIGH';
13
13
  const CRITICAL = 'CRITICAL';
14
14
  const APP_NAME = 'contrast';
15
- const APP_VERSION = '1.0.3';
15
+ const APP_VERSION = '1.0.4';
16
16
  const TIMEOUT = 120000;
17
17
  const AUTH_UI_URL = 'https://cli-auth.contrastsecurity.com';
18
18
  const AUTH_CALLBACK_URL = 'https://cli-auth-api.contrastsecurity.com';
@@ -25,9 +25,11 @@ const lambda = {
25
25
  loadingFunctionList: 'Loading lambda function list',
26
26
  functionsFound: '{{count}} functions found',
27
27
  noFunctionsFound: 'No functions found',
28
- failedToLoadFunctions: 'Faled to load lambda functions',
28
+ failedToLoadFunctions: 'Failed to load lambda functions',
29
29
  availableForScan: '{{icon}} {{count}} available for scan',
30
30
  runtimeCount: '----- {{runtime}} ({{count}}) -----',
31
+ gatherResults: 'Gathering results...',
32
+ doneGatherResults: 'Done gathering results',
31
33
  whatHappenedTitle: 'What happened:',
32
34
  whatHappenedItem: '{{policy}} have:\n{{comments}}\n',
33
35
  recommendation: 'Recommendation:',
@@ -10,8 +10,6 @@ const en_locales = () => {
10
10
  snapshotHostMessage: " No host supplied. Using default host 'app.contrastsecurity.com'. Please ensure this is correct.",
11
11
  vulnerabilitiesSuccessMessage: ' Vulnerability data successfully retrieved',
12
12
  vulnerabilitiesFailureMessage: ' Unable to retrieve library vulnerabilities from Team Server.',
13
- reportSuccessMessage: ' Report successfully retrieved',
14
- reportFailureMessage: ' Unable to generate library report.',
15
13
  catchErrorMessage: 'Contrast UI error: ',
16
14
  dependenciesNote: 'Please Note: We currently only support projects with one .csproj AND *.package.lock.json',
17
15
  languageAnalysisFailureMessage: 'LANGUAGE ANALYSIS FAILED',
@@ -111,7 +109,7 @@ const en_locales = () => {
111
109
  constantsCount: "The number of CVE's that must be exceeded to fail a build",
112
110
  constantsHeader: 'CodeSec by Contrast Security',
113
111
  constantsPrerequisitesContentScanLanguages: 'Java & JavaScript supported',
114
- constantsContrastContent: 'Use the Contrast CLI to run a scan(Java, JavaScript and .NET ) or lambda command (Java and Python) to find your vulnerabilities and start securing your code.',
112
+ constantsContrastContent: 'Use the Contrast CLI to run a scan (Java, JavaScript and .NET ) or lambda command (Java and Python) to find your vulnerabilities and start securing your code.',
115
113
  constantsUsageGuideContentRecommendation: 'Our recommendation is that this is invoked as part of a CI pipeline so that running the cli is automated as part of your build process.',
116
114
  constantsPrerequisitesHeader: 'Pre-requisites',
117
115
  constantsAuthUsageHeader: 'Usage',
@@ -175,7 +173,8 @@ const en_locales = () => {
175
173
  constantsTags: 'Apply labels to an application. Labels must be formatted as a comma-delimited list. Example - label1,label2,label3',
176
174
  constantsCode: 'Add the application code this application should use in the Contrast UI',
177
175
  constantsIgnoreCertErrors: ' For EOP users with a local Teamserver install, this will bypass the SSL certificate and recognise a self signed certificate.',
178
- constantsSave: ' Saves the Scan Results JSON to file.',
176
+ constantsSave: ' Saves the Scan Results SARIF to file.',
177
+ scanLabel: "adds a label to the scan - defaults to 'Started by CLI tool at current date'",
179
178
  constantsIgnoreDev: 'Combined with the --report command excludes developer dependencies from the vulnerabilities report. By default all dependencies are included in a report.',
180
179
  constantsCommands: 'Commands',
181
180
  constantsScanOptions: 'Scan Options',
@@ -184,7 +183,7 @@ const en_locales = () => {
184
183
  ignoreDevDep: 'No private libraries that are not scoped detected',
185
184
  foundExistingProjectScan: 'Found existing project...',
186
185
  projectCreatedScan: 'Project created',
187
- uploadingScan: 'Uploading...',
186
+ uploadingScan: 'Uploading file to scan.',
188
187
  uploadingScanSuccessful: 'Uploaded file successfully.',
189
188
  uploadingScanFail: 'Unable to upload the file.',
190
189
  waitingTimedOut: 'Timed out.',
@@ -194,6 +193,7 @@ const en_locales = () => {
194
193
  specifyFileScanError: 'Java Scan requires a .war or .jar file. Javascript Scan requires a .js or .zip file.\nTo start a Scan enter "contrast scan -f <path-to-file>"',
195
194
  populateProjectIdMessage: 'project ID is %s',
196
195
  genericServiceError: 'returned with status code %s',
196
+ projectIdError: 'Your project ID is %s please check this is correct',
197
197
  permissionsError: 'You do not have the correct permissions here. \n Contact support@contrastsecurity.com to get this fixed.',
198
198
  scanErrorFileMessage: 'We only accept the following file types: \nJava - .jar, .war \nJavaScript - .js or .zip files',
199
199
  helpAuthSummary: 'Authenticate Contrast using your Github or Google account',
@@ -231,13 +231,16 @@ const en_locales = () => {
231
231
  searchingScanFileDirectory: 'Searching for file to scan from %s...',
232
232
  scanHeader: 'Contrast Scan CLI',
233
233
  authHeader: 'Auth',
234
- lambdaHeader: 'Contrast lambda help',
234
+ lambdaHeader: 'Contrast Lambda CLI',
235
235
  lambdaSummary: 'Performs static security scan on an AWS Lambda Function.\nProduces CVE (Vulnerable Dependencies) and Least Privilege violations/remediation results.',
236
236
  lambdaUsage: 'contrast lambda --function-name <function> [options]',
237
- lambdaPrerequisitesContent: 'contrast cli',
238
- scanFileNameOption: ' -f, --file',
239
- lambdaFunctionNameOption: ' -f, --function-name',
240
- lambdaListFunctionsOption: ' -l, --list-functions',
237
+ lambdaPrerequisitesContent: '',
238
+ lambdaPrerequisitesContentLambdaLanguages: 'Supported runtimes: Java & Python',
239
+ lambdaPrerequisitesContentLambdaDescriptionTitle: 'AWS Requirements\n',
240
+ lambdaPrerequisitesContentLambdaDescription: 'Make sure you have the AWS credentials configured on your local environment. \nYou need the following AWS permissions configured on your IAM user:\n - Lambda: GetFunction, GetLayerVersionֿ\n - IAM: GetRolePolicy, GetPolicy, GetPolicyVersion, ListRolePolicies, ListAttachedRolePolicies',
241
+ scanFileNameOption: '-f, --file',
242
+ lambdaFunctionNameOption: '-f, --function-name',
243
+ lambdaListFunctionsOption: '-l, --list-functions',
241
244
  lambdaEndpointOption: '-e, --endpoint-url',
242
245
  lambdaRegionOption: '-r, --region',
243
246
  lambdaProfileOption: '-p, --profile',
@@ -290,6 +293,10 @@ const en_locales = () => {
290
293
  auditSBOMSaveSuccess: '\n Software Bill of Materials (SBOM) saved successfully',
291
294
  auditNoFiletypeSpecifiedForSave: `\n ${chalk.yellow.bold('No file type specified for --save option to save audit results to. Use audit --help to see valid --save options.')}`,
292
295
  auditBadFiletypeSpecifiedForSave: `\n ${chalk.yellow.bold('Bad file type specified for --save option. Use audit --help to see valid --save options.')}`,
296
+ auditReportWaiting: 'Waiting for report...',
297
+ auditReportFail: 'Report Retrieval Failed, please try again',
298
+ auditReportSuccessMessage: ' Report successfully retrieved',
299
+ auditReportFailureMessage: ' Unable to generate library report.',
293
300
  ...lambda
294
301
  };
295
302
  };
package/dist/constants.js CHANGED
@@ -116,6 +116,10 @@ const scanOptionDefinitions = [
116
116
  alias: 's',
117
117
  description: '{bold ' + i18n.__('constantsOptional') + '}:' + i18n.__('constantsSave')
118
118
  },
119
+ {
120
+ name: 'label',
121
+ description: '{bold ' + i18n.__('constantsOptional') + '}:' + i18n.__('scanLabel')
122
+ },
119
123
  {
120
124
  name: 'help',
121
125
  alias: 'h',
@@ -294,7 +298,7 @@ const mainUsageGuide = commandLineUsage([
294
298
  ]
295
299
  },
296
300
  {
297
- content: '{underline https://www.contrastsecurity.com}'
301
+ content: '{underline https://developer.contrastsecurity.com/} \n For technical support head to {underline https://support.contrastsecurity.com}'
298
302
  }
299
303
  ]);
300
304
  const mainDefinition = [{ name: 'command', defaultOption: true }];
package/dist/index.js CHANGED
@@ -36,12 +36,12 @@ const start = async () => {
36
36
  argvMain.includes('--v') ||
37
37
  argvMain.includes('--version')) {
38
38
  console.log(constants_2.APP_VERSION);
39
- await (0, versionChecker_1.findLatestCLIVersion)();
39
+ await (0, versionChecker_1.findLatestCLIVersion)(config.get('updateMessageHidden'));
40
40
  return;
41
41
  }
42
42
  config.set('numOfRuns', config.get('numOfRuns') + 1);
43
43
  if (config.get('numOfRuns') >= 5) {
44
- await (0, versionChecker_1.findLatestCLIVersion)();
44
+ await (0, versionChecker_1.findLatestCLIVersion)(config.get('updateMessageHidden'));
45
45
  config.set('numOfRuns', 0);
46
46
  }
47
47
  if (command === 'config') {
@@ -13,7 +13,15 @@ const lambdaUsageGuide = (0, command_line_usage_1.default)([
13
13
  },
14
14
  {
15
15
  header: i18n_1.default.__('constantsPrerequisitesHeader'),
16
- content: [i18n_1.default.__('lambdaPrerequisitesContent')]
16
+ content: [
17
+ '{bold ' +
18
+ i18n_1.default.__('lambdaPrerequisitesContentLambdaLanguages') +
19
+ '}\n\n' +
20
+ '{bold ' +
21
+ i18n_1.default.__('lambdaPrerequisitesContentLambdaDescriptionTitle') +
22
+ '}' +
23
+ i18n_1.default.__('lambdaPrerequisitesContentLambdaDescription')
24
+ ]
17
25
  },
18
26
  {
19
27
  header: i18n_1.default.__('constantsUsage'),
@@ -23,44 +31,44 @@ const lambdaUsageGuide = (0, command_line_usage_1.default)([
23
31
  header: i18n_1.default.__('constantsOptions'),
24
32
  content: [
25
33
  {
26
- name: i18n_1.default.__('lambdaFunctionNameOption'),
34
+ name: '{bold ' + i18n_1.default.__('lambdaFunctionNameOption') + '}',
27
35
  summary: i18n_1.default.__('lambdaFunctionNameSummery')
28
36
  },
29
37
  {
30
- name: i18n_1.default.__('lambdaListFunctionsOption'),
38
+ name: '{bold ' + i18n_1.default.__('lambdaListFunctionsOption') + '}',
31
39
  summary: i18n_1.default.__('lambdaListFunctionsSummery')
32
40
  },
33
41
  {
34
- name: i18n_1.default.__('lambdaEndpointOption'),
35
- summary: '{italic ' +
42
+ name: '{bold ' + i18n_1.default.__('lambdaEndpointOption') + '}',
43
+ summary: '{bold ' +
36
44
  i18n_1.default.__('constantsOptional') +
37
45
  '}: ' +
38
46
  i18n_1.default.__('lambdaEndpointSummery')
39
47
  },
40
48
  {
41
- name: i18n_1.default.__('lambdaRegionOption'),
42
- summary: '{italic ' +
49
+ name: '{bold ' + i18n_1.default.__('lambdaRegionOption') + '}',
50
+ summary: '{bold ' +
43
51
  i18n_1.default.__('constantsOptional') +
44
52
  '}: ' +
45
53
  i18n_1.default.__('lambdaRegionSummery')
46
54
  },
47
55
  {
48
- name: i18n_1.default.__('lambdaProfileOption'),
49
- summary: '{italic ' +
56
+ name: '{bold ' + i18n_1.default.__('lambdaProfileOption') + '}',
57
+ summary: '{bold ' +
50
58
  i18n_1.default.__('constantsOptional') +
51
59
  '}: ' +
52
60
  i18n_1.default.__('lambdaProfileSummery')
53
61
  },
54
62
  {
55
- name: i18n_1.default.__('lambdaJsonOption'),
56
- summary: '{italic ' +
63
+ name: '{bold ' + i18n_1.default.__('lambdaJsonOption') + '}',
64
+ summary: '{bold ' +
57
65
  i18n_1.default.__('constantsOptional') +
58
66
  '}: ' +
59
67
  i18n_1.default.__('lambdaJsonSummery')
60
68
  },
61
69
  {
62
- name: i18n_1.default.__('lambdaVerboseOption'),
63
- summary: '{italic ' +
70
+ name: '{bold ' + i18n_1.default.__('lambdaVerboseOption') + '}',
71
+ summary: '{bold ' +
64
72
  i18n_1.default.__('constantsOptional') +
65
73
  '}: ' +
66
74
  i18n_1.default.__('lambdaVerbosSummery')
@@ -73,7 +81,7 @@ const lambdaUsageGuide = (0, command_line_usage_1.default)([
73
81
  ]
74
82
  },
75
83
  {
76
- content: '{underline https://www.contrastsecurity.com}'
84
+ content: '{underline https://www.contrastsecurity.com/developer/codesec}'
77
85
  }
78
86
  ]);
79
87
  exports.lambdaUsageGuide = lambdaUsageGuide;
@@ -18,6 +18,8 @@ const scanRequest_1 = require("./scanRequest");
18
18
  const scanResults_1 = require("./scanResults");
19
19
  const utils_1 = require("./utils");
20
20
  const lambdaUtils_1 = require("./lambdaUtils");
21
+ const requestUtils_1 = require("../utils/requestUtils");
22
+ const oraWrapper_1 = __importDefault(require("../utils/oraWrapper"));
21
23
  const failedStates = [
22
24
  'UNSUPPORTED',
23
25
  'EXCLUDED',
@@ -101,6 +103,10 @@ const actualProcessLambda = async (lambdaOptions) => {
101
103
  description: failedScan.stateReasonText
102
104
  });
103
105
  }
106
+ const startGetherResultsSpinner = oraWrapper_1.default.returnOra(i18n_1.default.__('gatherResults'));
107
+ oraWrapper_1.default.startSpinner(startGetherResultsSpinner);
108
+ await (0, requestUtils_1.sleep)(15 * 1000);
109
+ oraWrapper_1.default.succeedSpinner(startGetherResultsSpinner, 'Done gathering results');
104
110
  const resultsResponse = await (0, scanResults_1.getScanResults)(auth, params, scanId, functionArn);
105
111
  if (jsonOutput) {
106
112
  console.log(JSON.stringify(resultsResponse?.data?.results, null, 2));
@@ -0,0 +1,10 @@
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.lineInfoSet = new Set;
8
+ }
9
+ }
10
+ 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;