@contrast/contrast 1.0.2 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/.prettierignore +4 -0
  2. package/README.md +24 -16
  3. package/dist/audit/autodetection/autoDetectLanguage.js +32 -0
  4. package/dist/audit/catalogueApplication/catalogueApplication.js +2 -11
  5. package/dist/audit/languageAnalysisEngine/{langugageAnalysisFactory.js → languageAnalysisFactory.js} +30 -13
  6. package/dist/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +25 -0
  7. package/dist/audit/languageAnalysisEngine/report/commonReportingFunctions.js +51 -237
  8. package/dist/audit/languageAnalysisEngine/report/models/reportLibraryModel.js +19 -0
  9. package/dist/audit/languageAnalysisEngine/report/models/reportListModel.js +24 -0
  10. package/dist/audit/languageAnalysisEngine/report/models/reportSeverityModel.js +10 -0
  11. package/dist/audit/languageAnalysisEngine/report/reportingFeature.js +24 -129
  12. package/dist/audit/languageAnalysisEngine/report/utils/reportUtils.js +85 -0
  13. package/dist/audit/languageAnalysisEngine/sendSnapshot.js +2 -14
  14. package/dist/commands/audit/auditConfig.js +8 -2
  15. package/dist/commands/audit/auditController.js +14 -5
  16. package/dist/commands/audit/saveFile.js +11 -0
  17. package/dist/commands/auth/auth.js +19 -1
  18. package/dist/commands/config/config.js +19 -8
  19. package/dist/commands/scan/processScan.js +13 -27
  20. package/dist/commands/scan/sca/scaAnalysis.js +44 -0
  21. package/dist/common/HTTPClient.js +29 -26
  22. package/dist/common/errorHandling.js +15 -39
  23. package/dist/common/versionChecker.js +32 -0
  24. package/dist/constants/constants.js +16 -2
  25. package/dist/constants/lambda.js +3 -1
  26. package/dist/constants/locales.js +58 -48
  27. package/dist/constants.js +59 -3
  28. package/dist/index.js +48 -30
  29. package/dist/lambda/help.js +22 -14
  30. package/dist/lambda/lambda.js +6 -0
  31. package/dist/sbom/generateSbom.js +20 -0
  32. package/dist/scaAnalysis/common/formatMessage.js +11 -0
  33. package/dist/scaAnalysis/common/treeUpload.js +30 -0
  34. package/dist/scaAnalysis/java/analysis.js +116 -0
  35. package/dist/scaAnalysis/java/index.js +18 -0
  36. package/dist/scaAnalysis/java/javaBuildDepsParser.js +326 -0
  37. package/dist/scan/autoDetection.js +46 -1
  38. package/dist/scan/fileUtils.js +73 -1
  39. package/dist/scan/formatScanOutput.js +212 -0
  40. package/dist/scan/help.js +6 -2
  41. package/dist/scan/models/groupedResultsModel.js +11 -0
  42. package/dist/scan/models/resultContentModel.js +2 -0
  43. package/dist/scan/models/scanResultsModel.js +11 -0
  44. package/dist/scan/populateProjectIdAndProjectName.js +1 -0
  45. package/dist/scan/saveResults.js +9 -10
  46. package/dist/scan/scan.js +26 -101
  47. package/dist/scan/scanConfig.js +20 -1
  48. package/dist/scan/scanController.js +8 -4
  49. package/dist/scan/scanResults.js +8 -17
  50. package/dist/utils/getConfig.js +3 -0
  51. package/dist/utils/requestUtils.js +1 -1
  52. package/dist/utils/saveFile.js +19 -0
  53. package/package.json +3 -2
  54. package/src/audit/autodetection/autoDetectLanguage.ts +40 -0
  55. package/src/audit/catalogueApplication/catalogueApplication.js +4 -16
  56. package/src/audit/languageAnalysisEngine/{langugageAnalysisFactory.js → languageAnalysisFactory.js} +41 -19
  57. package/src/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +71 -0
  58. package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.ts +105 -0
  59. package/src/audit/languageAnalysisEngine/report/models/reportLibraryModel.ts +30 -0
  60. package/src/audit/languageAnalysisEngine/report/models/reportListModel.ts +32 -0
  61. package/src/audit/languageAnalysisEngine/report/models/reportSeverityModel.ts +9 -0
  62. package/src/audit/languageAnalysisEngine/report/reportingFeature.ts +56 -0
  63. package/src/audit/languageAnalysisEngine/report/utils/reportUtils.ts +110 -0
  64. package/src/audit/languageAnalysisEngine/sendSnapshot.js +2 -22
  65. package/src/commands/audit/auditConfig.ts +12 -3
  66. package/src/commands/audit/auditController.ts +21 -5
  67. package/src/commands/audit/processAudit.ts +3 -1
  68. package/src/commands/audit/saveFile.ts +6 -0
  69. package/src/commands/auth/auth.js +25 -1
  70. package/src/commands/config/config.js +22 -8
  71. package/src/commands/scan/processScan.js +15 -31
  72. package/src/commands/scan/sca/scaAnalysis.js +73 -0
  73. package/src/common/HTTPClient.js +42 -36
  74. package/src/common/errorHandling.ts +17 -48
  75. package/src/common/versionChecker.ts +41 -0
  76. package/src/constants/constants.js +17 -4
  77. package/src/constants/lambda.js +3 -1
  78. package/src/constants/locales.js +69 -63
  79. package/src/constants.js +66 -3
  80. package/src/index.ts +62 -36
  81. package/src/lambda/help.ts +22 -14
  82. package/src/lambda/lambda.ts +8 -0
  83. package/src/sbom/generateSbom.ts +17 -0
  84. package/src/scaAnalysis/common/formatMessage.js +10 -0
  85. package/src/scaAnalysis/common/treeUpload.js +34 -0
  86. package/src/scaAnalysis/java/analysis.js +159 -0
  87. package/src/scaAnalysis/java/index.js +21 -0
  88. package/src/scaAnalysis/java/javaBuildDepsParser.js +391 -0
  89. package/src/scan/autoDetection.js +54 -1
  90. package/src/scan/fileUtils.js +91 -1
  91. package/src/scan/formatScanOutput.ts +241 -0
  92. package/src/scan/help.js +6 -2
  93. package/src/scan/models/groupedResultsModel.ts +20 -0
  94. package/src/scan/models/resultContentModel.ts +86 -0
  95. package/src/scan/models/scanResultsModel.ts +52 -0
  96. package/src/scan/populateProjectIdAndProjectName.js +1 -0
  97. package/src/scan/saveResults.js +8 -9
  98. package/src/scan/scan.ts +62 -0
  99. package/src/scan/scanConfig.js +26 -1
  100. package/src/scan/scanController.js +12 -4
  101. package/src/scan/scanResults.js +19 -17
  102. package/src/utils/getConfig.ts +12 -0
  103. package/src/utils/requestUtils.js +1 -1
  104. package/src/utils/saveFile.js +19 -0
  105. package/dist/audit/languageAnalysisEngine/report/checkIgnoreDevDep.js +0 -17
  106. package/dist/audit/languageAnalysisEngine/report/newReportingFeature.js +0 -81
  107. package/dist/common/findLatestCLIVersion.js +0 -23
  108. package/src/audit/languageAnalysisEngine/report/checkIgnoreDevDep.js +0 -27
  109. package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.js +0 -303
  110. package/src/audit/languageAnalysisEngine/report/newReportingFeature.js +0 -124
  111. package/src/audit/languageAnalysisEngine/report/reportingFeature.js +0 -190
  112. package/src/common/findLatestCLIVersion.ts +0 -27
  113. package/src/scan/scan.js +0 -167
@@ -1,5 +1,4 @@
1
1
  import i18n from 'i18n'
2
- import { sortBy } from 'lodash'
3
2
 
4
3
  const handleResponseErrors = (res: any, api: string) => {
5
4
  if (res.statusCode === 400) {
@@ -28,30 +27,15 @@ const libraryAnalysisError = () => {
28
27
  }
29
28
 
30
29
  const snapshotFailureError = () => {
31
- console.log(
32
- '\n ******************************** ' +
33
- i18n.__('snapshotFailureHeader') +
34
- ' *********************************\n' +
35
- i18n.__('snapshotFailureMessage')
36
- )
30
+ console.log(i18n.__('snapshotFailureMessage'))
37
31
  }
38
32
 
39
33
  const vulnerabilitiesFailureError = () => {
40
- console.log(
41
- '\n ******************************** ' +
42
- i18n.__('snapshotFailureHeader') +
43
- ' *********************************\n' +
44
- i18n.__('vulnerabilitiesFailureMessage')
45
- )
34
+ console.log(i18n.__('vulnerabilitiesFailureMessage'))
46
35
  }
47
36
 
48
37
  const reportFailureError = () => {
49
- console.log(
50
- '\n ******************************** ' +
51
- i18n.__('snapshotFailureHeader') +
52
- ' *********************************\n' +
53
- i18n.__('reportFailureMessage')
54
- )
38
+ console.log(i18n.__('auditReportFailureMessage'))
55
39
  }
56
40
 
57
41
  const genericError = (missingCliOption: string) => {
@@ -73,16 +57,13 @@ const badRequestError = (catalogue: boolean) => {
73
57
 
74
58
  const forbiddenError = () => {
75
59
  generalError('forbiddenRequestErrorHeader', 'forbiddenRequestErrorMessage')
60
+ process.exit(1)
76
61
  }
77
62
 
78
63
  const proxyError = () => {
79
64
  generalError('proxyErrorHeader', 'proxyErrorMessage')
80
65
  }
81
66
 
82
- const hostWarningError = () => {
83
- console.log(i18n.__('snapshotHostMessage'))
84
- }
85
-
86
67
  const failOptionError = () => {
87
68
  console.log(
88
69
  '\n ******************************** ' +
@@ -120,7 +101,7 @@ const generalError = (header: string, message?: string) => {
120
101
  console.log(finalMessage)
121
102
  }
122
103
 
123
- const approximateCommandOnError = (unknownOptions: string[]) => {
104
+ const findCommandOnError = (unknownOptions: string[]) => {
124
105
  const commandKeywords = {
125
106
  auth: 'auth',
126
107
  audit: 'audit',
@@ -128,34 +109,20 @@ const approximateCommandOnError = (unknownOptions: string[]) => {
128
109
  lambda: 'lambda',
129
110
  config: 'config'
130
111
  }
131
- const sortedUnknownOptions = sortBy(unknownOptions, param =>
132
- param === 'auth' ||
133
- param === 'audit' ||
134
- param === 'scan' ||
135
- param === 'lambda' ||
136
- param === 'config'
137
- ? 0
138
- : 1
139
- )
140
112
 
141
- const foundCommands = sortedUnknownOptions.filter(
113
+ const containsCommandKeyword = unknownOptions.some(
142
114
  // @ts-ignore
143
115
  command => commandKeywords[command]
144
116
  )
145
117
 
146
- const parsedUnknownOptions = sortedUnknownOptions
147
- .toString()
148
- .replace(/,/g, ' ')
149
-
150
- const approximateParams = parsedUnknownOptions
151
- .replace(new RegExp(foundCommands.join('|'), 'g'), '')
152
- .trim()
153
-
154
- const approximateCommand = `${foundCommands[0]} ${approximateParams}`
118
+ if (containsCommandKeyword) {
119
+ const foundCommands = unknownOptions.filter(
120
+ // @ts-ignore
121
+ command => commandKeywords[command]
122
+ )
155
123
 
156
- return {
157
- approximateCommand,
158
- approximateCommandKeyword: foundCommands[0]
124
+ //return the first command found
125
+ return foundCommands[0]
159
126
  }
160
127
  }
161
128
 
@@ -166,10 +133,12 @@ export {
166
133
  forbiddenError,
167
134
  proxyError,
168
135
  failOptionError,
169
- hostWarningError,
170
136
  generalError,
171
137
  getErrorMessage,
172
138
  handleResponseErrors,
173
139
  libraryAnalysisError,
174
- approximateCommandOnError
140
+ findCommandOnError,
141
+ snapshotFailureError,
142
+ vulnerabilitiesFailureError,
143
+ reportFailureError
175
144
  }
@@ -0,0 +1,41 @@
1
+ import latestVersion from 'latest-version'
2
+ import { APP_VERSION } from '../constants/constants'
3
+ import boxen from 'boxen'
4
+ import chalk from 'chalk'
5
+ import semver from 'semver'
6
+
7
+ export async function findLatestCLIVersion(updateMessageHidden: boolean) {
8
+ if (!updateMessageHidden) {
9
+ const latestCLIVersion = await latestVersion('@contrast/contrast')
10
+
11
+ if (semver.lt(APP_VERSION, latestCLIVersion)) {
12
+ const updateAvailableMessage = `Update available ${chalk.yellow(
13
+ APP_VERSION
14
+ )} → ${chalk.green(latestCLIVersion)}`
15
+
16
+ const npmUpdateAvailableCommand = `Run ${chalk.cyan(
17
+ 'npm i @contrast/contrast -g'
18
+ )} to update via npm`
19
+
20
+ const homebrewUpdateAvailableCommand = `Run ${chalk.cyan(
21
+ 'brew install contrastsecurity/tap/contrast'
22
+ )} to update via brew`
23
+
24
+ console.log(
25
+ boxen(
26
+ `${updateAvailableMessage}\n${npmUpdateAvailableCommand}\n\n${homebrewUpdateAvailableCommand}`,
27
+ {
28
+ titleAlignment: 'center',
29
+ margin: 1,
30
+ padding: 1,
31
+ align: 'center'
32
+ }
33
+ )
34
+ )
35
+ }
36
+ }
37
+ }
38
+
39
+ export async function isCorrectNodeVersion(currentVersion: string) {
40
+ return semver.satisfies(currentVersion, '>=16.13.2 <17')
41
+ }
@@ -8,17 +8,23 @@ const GO = 'GO'
8
8
  // we set the langauge as Node instead of PHP since we're using the Node engine in TS
9
9
  const PHP = 'PHP'
10
10
  const JAVASCRIPT = 'JAVASCRIPT'
11
-
12
11
  const LOW = 'LOW'
13
12
  const MEDIUM = 'MEDIUM'
14
13
  const HIGH = 'HIGH'
15
14
  const CRITICAL = 'CRITICAL'
16
-
17
15
  const APP_NAME = 'contrast'
18
- const APP_VERSION = '1.0.2'
16
+ const APP_VERSION = '1.0.5'
19
17
  const TIMEOUT = 120000
18
+ const HIGH_COLOUR = '#ff9900'
19
+ const CRITICAL_COLOUR = '#e35858'
20
+ const MEDIUM_COLOUR = '#f1c232'
21
+ const LOW_COLOUR = '#ff9900'
22
+ const NOTE_COLOUR = '#999999'
23
+
20
24
  const AUTH_UI_URL = 'https://cli-auth.contrastsecurity.com'
21
25
  const AUTH_CALLBACK_URL = 'https://cli-auth-api.contrastsecurity.com'
26
+ const SARIF_FILE = 'SARIF'
27
+ const CE_URL = 'https://ce.contrastsecurity.com/'
22
28
 
23
29
  module.exports = {
24
30
  supportedLanguages: { NODE, DOTNET, JAVA, RUBY, PYTHON, GO, PHP, JAVASCRIPT },
@@ -30,5 +36,12 @@ module.exports = {
30
36
  APP_NAME,
31
37
  TIMEOUT,
32
38
  AUTH_UI_URL,
33
- AUTH_CALLBACK_URL
39
+ AUTH_CALLBACK_URL,
40
+ SARIF_FILE,
41
+ HIGH_COLOUR,
42
+ CRITICAL_COLOUR,
43
+ MEDIUM_COLOUR,
44
+ LOW_COLOUR,
45
+ NOTE_COLOUR,
46
+ CE_URL
34
47
  }
@@ -36,11 +36,13 @@ const lambda = {
36
36
  loadingFunctionList: 'Loading lambda function list',
37
37
  functionsFound: '{{count}} functions found',
38
38
  noFunctionsFound: 'No functions found',
39
- failedToLoadFunctions: 'Faled to load lambda functions',
39
+ failedToLoadFunctions: 'Failed to load lambda functions',
40
40
  availableForScan: '{{icon}} {{count}} available for scan',
41
41
  runtimeCount: '----- {{runtime}} ({{count}}) -----',
42
42
 
43
43
  // ====== print vulnerabilities ===== //
44
+ gatherResults: 'Gathering results...',
45
+ doneGatherResults: 'Done gathering results',
44
46
  whatHappenedTitle: 'What happened:',
45
47
  whatHappenedItem: '{{policy}} have:\n{{comments}}\n',
46
48
  recommendation: 'Recommendation:',
@@ -5,48 +5,29 @@ const en_locales = () => {
5
5
  return {
6
6
  successHeader: 'SUCCESS',
7
7
  snapshotSuccessMessage:
8
- ' Please go to the Contrast UI to view your dependency tree.',
8
+ 'Please go to the Contrast UI to view your dependency tree.',
9
9
  snapshotFailureHeader: 'FAIL',
10
- snapshotFailureMessage:
11
- ' Unable to send library analysis to your Contrast UI.',
10
+ snapshotFailureMessage: 'Library analysis failed',
12
11
  snapshotHostMessage:
13
- " No host supplied. Using default host 'app.contrastsecurity.com'. Please ensure this is correct.",
14
- vulnerabilitiesSuccessMessage: ' Vulnerability data successfully retrieved',
15
- vulnerabilitiesFailureMessage:
16
- ' Unable to retrieve library vulnerabilities from Team Server.',
17
- reportSuccessMessage: ' Report successfully retrieved',
18
- reportFailureMessage: ' Unable to generate library report.',
12
+ "No host supplied. Using default host 'app.contrastsecurity.com'. Please ensure this is correct.",
13
+ vulnerabilitiesSuccessMessage: 'Vulnerability data successfully retrieved',
14
+ vulnerabilitiesFailureMessage: 'Unable to retrieve library vulnerabilities',
19
15
  catchErrorMessage: 'Contrast UI error: ',
20
16
  dependenciesNote:
21
17
  'Please Note: We currently only support projects with one .csproj AND *.package.lock.json',
22
- languageAnalysisFailureMessage: 'LANGUAGE ANALYSIS FAILED',
18
+ languageAnalysisFailureMessage: 'SCA Analysis Failure',
23
19
  languageAnalysisFactoryFailureHeader: 'FAIL',
24
- projectPathParameter:
25
- 'Please set the %s to locate the source code for the project',
26
- apiKeyParameter: 'Please set the %s to connect to the Contrast UI',
27
- applicationNameParameter:
28
- 'Please provide a value for %s, to appear in the Contrast UI',
29
- languageParameter:
30
- 'Please set the %s to the language of the source project. Allowable values are JAVA, DOTNET, NODE, PYTHON and RUBY.',
31
- hostParameter:
32
- 'Please set the %s to the hostname and (optionally) the port expressed as <host>:<port> of the Contrast UI',
33
- organizationIdParameter:
34
- 'Please set the %s to correctly identify your organization within the Contrast UI',
35
- authorizationParameter:
36
- 'Please set the %s to your authorization header, found in the Contrast UI',
37
- applicationIdParameter:
38
- 'Please set the %s to the value provided within the Contrast UI for the target application',
39
20
  libraryAnalysisError:
40
- 'Please ensure the language parameter is set in accordance to the language specified on the project path.\nThe Contrast-CLI must be run in the same directory as the project manifest file OR the project_path parameter must be used to identify the directory containing the project manifest file.\n\nFor further information please read our usage guide, which can be accessed with the following command:\n\ncontrast-cli --help',
21
+ 'Please ensure the language parameter is set in accordance to the language specified on the project path.\nContrast CLI must be run in the same directory as the project manifest file OR the project_path parameter must be used to identify the directory containing the project manifest file.\n\nFor further information please read our usage guide, which can be accessed with the following command:\n\ncontrast-cli --help',
41
22
  yamlMissingParametersHeader: 'Missing Parameters',
42
23
  yamlMissingParametersMessage:
43
- 'The following parameters are required: \n \norganization_id \napi_key \nauthorization \nhost \napplication_name or application_id \nlanguage \n \nThey must be specified as a command line argument or within the yaml file. \nFor further information please read our usage guide, which can be accessed with the following command:\ncontrast-cli --help',
24
+ 'The following parameters are required: \n \norganization-id \napi-key \nauthorization \nhost \nlanguage \n \nThey must be specified as a command line argument. \nFor further information please read our usage guide, which can be accessed with the following command:\ncontrast audit --help',
44
25
  unauthenticatedErrorHeader: '401 error - Unauthenticated',
45
26
  unauthenticatedErrorMessage:
46
- 'Please check the following keys are correct:\n--organization_id, --api_key or --authorization',
27
+ 'Please check the following keys are correct:\n--organization-id, --api-key or --authorization',
47
28
  badRequestErrorHeader: '400 error - Bad Request',
48
29
  badRequestErrorMessage:
49
- 'Please check the following key is correct: \n--application_id',
30
+ 'Please check the following key is correct: \n--application-id',
50
31
  badRequestCatalogueErrorMessage:
51
32
  'The application name already exists, please use a unique name',
52
33
  forbiddenRequestErrorHeader: '403 error - Forbidden',
@@ -55,15 +36,7 @@ const en_locales = () => {
55
36
  proxyErrorHeader: '407 error - Proxy Authentication Required',
56
37
  proxyErrorMessage:
57
38
  'Please provide valid authentication credentials for the proxy server.',
58
- downgradeHttpsHttp:
59
- 'Connection to ContrastUI using https failed. Attempting to connect using http...',
60
- setSpecifiedParameter: 'Please set the %s ',
61
- catalogueFailureCommand:
62
- 'Failed to catalogue a new application for reason: ',
63
- catalogueFailureHostCommand:
64
- 'Failed to catalogue a new application, please ensure you have the correct host and authentication. Error: ',
65
- catalogueSuccessCommand:
66
- 'This application ID can now be used to send dependency data to Contrast: ',
39
+ catalogueSuccessCommand: 'Application Created',
67
40
  dotnetAnalysisFailure: '.NET analysis failed because: ',
68
41
  dotnetReadLockfile: 'Failed to read the lock file @ %s because: ',
69
42
  dotnetParseLockfile: "Failed to parse .NET lock file @ '%s' because: ",
@@ -131,12 +104,10 @@ const en_locales = () => {
131
104
  constantsOptionalForCatalogue: '(optional for catalogue)',
132
105
  constantsRequired: '(required)',
133
106
  constantsRequiredCatalogue: '(required for catalogue)',
134
- constantsYamlPath:
135
- 'If you want to read params from the yaml file then enter the path to the file',
136
107
  constantsApiKey: 'An agent API key as provided by Contrast UI',
137
108
  constantsAuthorization:
138
- 'An agent Authorization credentials as provided by Contrast UI',
139
- constantsOrganizationId: 'The ID of your organization in Contrast UI',
109
+ 'Authorization credentials as provided by Contrast UI',
110
+ constantsOrganizationId: 'The ID of your organization',
140
111
  constantsApplicationId:
141
112
  'The ID of the application cataloged by Contrast UI',
142
113
  constantsHostId:
@@ -172,13 +143,19 @@ const en_locales = () => {
172
143
  constantsSeverity:
173
144
  'Combined with the --report command, allows the user to report libraries with vulnerabilities above a chosen severity level. For example, cve_severity medium only reports libraries with vulnerabilities at medium or higher severity. Values for level are high, medium or low.',
174
145
  constantsCount: "The number of CVE's that must be exceeded to fail a build",
175
- constantsHeader: 'Contrast CLI',
146
+ constantsHeader: 'CodeSec by Contrast Security',
176
147
  constantsPrerequisitesContentScanLanguages: 'Java & JavaScript supported',
177
148
  constantsContrastContent:
178
- 'Use the Contrast CLI, the fastest and most accurate code scan, to help find and eliminate security bugs in your code.',
149
+ '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.',
179
150
  constantsUsageGuideContentRecommendation:
180
151
  '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.',
181
152
  constantsPrerequisitesHeader: 'Pre-requisites',
153
+ constantsAuthUsageHeader: 'Usage',
154
+ constantsAuthUsageContents: 'contrast auth',
155
+ constantsAuthHeaderContents:
156
+ 'Authorize with external identity provider to perform scans on code',
157
+ configHeader: 'Config',
158
+ constantsConfigUsageContents: 'view / clear the configuration',
182
159
  constantsPrerequisitesContent:
183
160
  'To scan a Java project you will need a .jar or .war file for analysis\n' +
184
161
  'To scan a Javascript project you will need a .js or.zip file for analysis\n' +
@@ -186,7 +163,7 @@ const en_locales = () => {
186
163
  constantsUsage: 'Usage',
187
164
  constantsUsageCommandExample: 'contrast [command] [options]',
188
165
  constantsUsageCommandInfo:
189
- 'The file argument is optional. If no file is given, Contrast will search for a .jar, .war, .js, .exe or .zip file in the working directory.\n',
166
+ 'The file argument is optional. If no file is given, Contrast will search for a .jar, .war, .exe or .zip file in the working directory.\n',
190
167
  constantsUsageCommandInfo24Hours:
191
168
  'Submitted files are encrypted during upload and deleted in 24 hours.',
192
169
  constantsAnd: 'AND',
@@ -249,17 +226,17 @@ const en_locales = () => {
249
226
  goAnalysisError: 'GO analysis failed because: ',
250
227
  goParseProjectFile: 'Failed to parse go mod graph output because: ',
251
228
  mavenNotInstalledError:
252
- " 'mvn' is not available. Please ensure you have Maven installed and available on your path.",
229
+ "'mvn' is not available. Please ensure you have Maven installed and available on your path.",
253
230
  mavenDependencyTreeNonZero:
254
231
  'Building maven dependancy tree failed with a non 0 exit code',
255
232
  gradleWrapperUnavailable:
256
- ' Gradle wrapper not found in root of project. Please ensure gradlew or gradlew.bat is in root of the project.',
233
+ 'Gradle wrapper not found in root of project. Please ensure gradlew or gradlew.bat is in root of the project.',
257
234
  gradleDependencyTreeNonZero:
258
235
  "Building gradle dependancy tree failed with a non 0 exit code. \n Please check you have the correct version of Java installed to compile your project? \n If running against a muti module project ensure you are using the '--sub-project' flag",
259
236
  yamlPathCamelCaseError:
260
- ' Warning: The "yamlPath" parameter will be deprecated in a future release. Please look at our documentation for further guidance.',
237
+ 'Warning: The "yamlPath" parameter will be deprecated in a future release. Please look at our documentation for further guidance.',
261
238
  constantsSbom:
262
- ' Generate the Software Bill of Materials (SBOM) for the given application',
239
+ 'Generate the Software Bill of Materials (SBOM) for the given application',
263
240
  constantsMetadata:
264
241
  'Define a set of key=value pairs (which conforms to RFC 2253) for specifying user-defined metadata associated with the application.',
265
242
  constantsTags:
@@ -267,8 +244,10 @@ const en_locales = () => {
267
244
  constantsCode:
268
245
  'Add the application code this application should use in the Contrast UI',
269
246
  constantsIgnoreCertErrors:
270
- ' For EOP users with a local Teamserver install, this will bypass the SSL certificate and recognise a self signed certificate.',
271
- constantsSave: ' Saves the Scan Results JSON to file.',
247
+ 'For EOP users with a local Teamserver install, this will bypass the SSL certificate and recognise a self signed certificate.',
248
+ constantsSave: 'Saves the Scan Results SARIF to file.',
249
+ scanLabel:
250
+ "adds a label to the scan - defaults to 'Started by CLI tool at current date'",
272
251
  constantsIgnoreDev:
273
252
  'Combined with the --report command excludes developer dependencies from the vulnerabilities report. By default all dependencies are included in a report.',
274
253
  constantsCommands: 'Commands',
@@ -278,26 +257,27 @@ const en_locales = () => {
278
257
  ignoreDevDep: 'No private libraries that are not scoped detected',
279
258
  foundExistingProjectScan: 'Found existing project...',
280
259
  projectCreatedScan: 'Project created',
281
- uploadingScan: 'Uploading...',
260
+ uploadingScan: 'Uploading file to scan.',
282
261
  uploadingScanSuccessful: 'Uploaded file successfully.',
283
262
  uploadingScanFail: 'Unable to upload the file.',
284
263
  waitingTimedOut: 'Timed out.',
285
264
  responseMessage: 'Response: %s',
286
265
  searchingDirectoryScan: 'Searched 3 directory levels & found: ',
287
266
  noFileFoundScan:
288
- "We could't find a suitable file in your directories (we go 3 deep)",
267
+ "We couldn't find a suitable file in your directories (we go 3 deep)",
289
268
  specifyFileScanError:
290
269
  '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>"',
270
+ specifyFileAuditNotFound: 'No files found for library analysis',
291
271
  populateProjectIdMessage: 'project ID is %s',
292
272
  genericServiceError: 'returned with status code %s',
273
+ projectIdError: 'Your project ID is %s please check this is correct',
293
274
  permissionsError:
294
275
  'You do not have the correct permissions here. \n Contact support@contrastsecurity.com to get this fixed.',
295
276
  scanErrorFileMessage:
296
277
  'We only accept the following file types: \nJava - .jar, .war \nJavaScript - .js or .zip files',
297
278
  helpAuthSummary:
298
279
  'Authenticate Contrast using your Github or Google account',
299
- helpScanSummary:
300
- 'Searches for a .jar, .war, .js or .zip file in the working directory, uploads for analysis and returns the results',
280
+ helpScanSummary: 'Perform static analysis on binaries / code artifacts',
301
281
  helpLambdaSummary: 'Perform scan on AWS Lambda functions',
302
282
  helpVersionSummary: 'Displays version of Contrast CLI',
303
283
  helpConfigSummary: 'Displays stored credentials',
@@ -308,6 +288,7 @@ const en_locales = () => {
308
288
  versionName: 'version',
309
289
  configName: 'config',
310
290
  helpName: 'help',
291
+ scanOptionsLanguageSummary: 'Valid values are JAVA, JAVASCRIPT and DOTNET',
311
292
  scanOptionsLanguageSummaryOptional:
312
293
  'Language of file to send for analysis. ',
313
294
  scanOptionsLanguageSummaryRequired:
@@ -315,7 +296,7 @@ const en_locales = () => {
315
296
  scanOptionsTimeoutSummary:
316
297
  'Time in seconds to wait for scan to complete. Default value is 300 seconds.',
317
298
  scanOptionsFileNameSummary:
318
- 'Path of the file you want to scan. If no file is specified, Contrast searches for a .jar, .war, .js, .exe or .zip file in the working directory.',
299
+ 'Path of the file you want to scan. If no file is specified, Contrast searches for a .jar, .war, .exe or .zip file in the working directory.',
319
300
  scanOptionsVerboseSummary: ' Returns extended information to the terminal.',
320
301
  authSuccessMessage: 'Authentication successful',
321
302
  runAuthSuccessMessage:
@@ -326,7 +307,7 @@ const en_locales = () => {
326
307
  zipErrorScan:
327
308
  'We only support zip files for JAVASCRIPT language, please set the flag --language JAVASCRIPT',
328
309
  unknownFileErrorScan: 'Unsupported file selected for Scan.',
329
- foundScanFile: 'found: %s',
310
+ foundScanFile: 'Found: %s',
330
311
  foundDetailedVulnerabilities:
331
312
  chalk.bold('%s Critical') +
332
313
  ' | ' +
@@ -335,15 +316,23 @@ const en_locales = () => {
335
316
  requiredParams: 'All required parameters are not present.',
336
317
  timeoutScan: 'Timeout set to 5 minutes.',
337
318
  searchingScanFileDirectory: 'Searching for file to scan from %s...',
319
+ searchingAuditFileDirectory:
320
+ 'Searching for package manager files from %s...',
338
321
  scanHeader: 'Contrast Scan CLI',
339
- lambdaHeader: 'Contrast lambda help',
322
+ authHeader: 'Auth',
323
+ lambdaHeader: 'Contrast Lambda CLI',
340
324
  lambdaSummary:
341
325
  'Performs static security scan on an AWS Lambda Function.\nProduces CVE (Vulnerable Dependencies) and Least Privilege violations/remediation results.',
342
326
  lambdaUsage: 'contrast lambda --function-name <function> [options]',
343
- lambdaPrerequisitesContent: 'contrast cli',
344
- scanFileNameOption: ' -f, --file',
345
- lambdaFunctionNameOption: ' -f, --function-name',
346
- lambdaListFunctionsOption: ' -l, --list-functions',
327
+ lambdaPrerequisitesContent: '',
328
+ lambdaPrerequisitesContentLambdaLanguages:
329
+ 'Supported runtimes: Java & Python',
330
+ lambdaPrerequisitesContentLambdaDescriptionTitle: 'AWS Requirements\n',
331
+ lambdaPrerequisitesContentLambdaDescription:
332
+ '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',
333
+ scanFileNameOption: '-f, --file',
334
+ lambdaFunctionNameOption: '-f, --function-name',
335
+ lambdaListFunctionsOption: '-l, --list-functions',
347
336
  lambdaEndpointOption: '-e, --endpoint-url',
348
337
  lambdaRegionOption: '-r, --region',
349
338
  lambdaProfileOption: '-p, --profile',
@@ -404,9 +393,26 @@ const en_locales = () => {
404
393
  auditOptionsSave: '-s, --save',
405
394
  auditOptionsSaveDescription:
406
395
  'saves the output in specified format Txt text, sbom',
396
+ scanNotCompleted:
397
+ 'Scan not completed. Check for framework and language support here: %s',
407
398
  scanNoVulnerabilitiesFound: '👏 No vulnerabilities found',
399
+ scanNoVulnerabilitiesFoundSecureCode: '👍 Your code looks secure.',
400
+ scanNoVulnerabilitiesFoundGoodWork: '👏 Keep up the good work.',
408
401
  scanNoFiletypeSpecifiedForSave:
409
- 'Please specify file type to save results to',
402
+ 'Please specify file type to save results to, accepted value is SARIF',
403
+ auditSBOMSaveSuccess:
404
+ '\n Software Bill of Materials (SBOM) saved successfully',
405
+ auditNoFiletypeSpecifiedForSave: `\n ${chalk.yellow.bold(
406
+ 'No file type specified for --save option to save audit results to. Use audit --help to see valid --save options.'
407
+ )}`,
408
+ auditBadFiletypeSpecifiedForSave: `\n ${chalk.yellow.bold(
409
+ 'Bad file type specified for --save option. Use audit --help to see valid --save options.'
410
+ )}`,
411
+ auditReportWaiting: 'Waiting for report...',
412
+ auditReportFail: 'Report Retrieval Failed, please try again',
413
+ auditReportSuccessMessage: 'Report successfully retrieved',
414
+ auditReportFailureMessage: 'Unable to generate library report',
415
+ auditSCAAnalysisBegins: 'Contrast SCA analysis begins',
410
416
  ...lambda
411
417
  }
412
418
  }
package/src/constants.js CHANGED
@@ -20,6 +20,15 @@ const scanOptionDefinitions = [
20
20
  '}: ' +
21
21
  i18n.__('constantsProjectName')
22
22
  },
23
+ {
24
+ name: 'language',
25
+ alias: 'l',
26
+ description:
27
+ '{bold ' +
28
+ i18n.__('constantsOptional') +
29
+ '}: ' +
30
+ i18n.__('scanOptionsLanguageSummary')
31
+ },
23
32
  {
24
33
  name: 'file',
25
34
  alias: 'f',
@@ -38,6 +47,15 @@ const scanOptionDefinitions = [
38
47
  '}: ' +
39
48
  i18n.__('constantsProjectId')
40
49
  },
50
+ {
51
+ name: 'project-path',
52
+ alias: 'i',
53
+ description:
54
+ '{bold ' +
55
+ i18n.__('constantsOptional') +
56
+ '}: ' +
57
+ i18n.__('constantsProjectPath')
58
+ },
41
59
  {
42
60
  name: 'timeout',
43
61
  alias: 't',
@@ -75,7 +93,6 @@ const scanOptionDefinitions = [
75
93
  },
76
94
  {
77
95
  name: 'host',
78
- alias: 'h',
79
96
  description:
80
97
  '{bold ' +
81
98
  i18n.__('constantsRequired') +
@@ -124,14 +141,56 @@ const scanOptionDefinitions = [
124
141
  description:
125
142
  '{bold ' + i18n.__('constantsOptional') + '}:' + i18n.__('constantsSave')
126
143
  },
144
+ {
145
+ name: 'label',
146
+ description:
147
+ '{bold ' + i18n.__('constantsOptional') + '}:' + i18n.__('scanLabel')
148
+ },
127
149
  {
128
150
  name: 'help',
151
+ alias: 'h',
129
152
  type: Boolean
130
153
  },
131
154
  {
132
155
  name: 'debug',
133
156
  alias: 'd',
134
157
  type: Boolean
158
+ },
159
+ {
160
+ name: 'experimental',
161
+ alias: 'e',
162
+ type: Boolean
163
+ },
164
+ {
165
+ name: 'application-name',
166
+ description:
167
+ '{bold ' +
168
+ i18n.__('constantsOptional') +
169
+ '}: ' +
170
+ i18n.__('constantsApplicationName')
171
+ }
172
+ ]
173
+
174
+ const authOptionDefinitions = [
175
+ {
176
+ name: 'help',
177
+ alias: 'h',
178
+ type: Boolean
179
+ }
180
+ ]
181
+
182
+ const configOptionDefinitions = [
183
+ {
184
+ name: 'help',
185
+ alias: 'h',
186
+ type: Boolean,
187
+ description: 'Help text'
188
+ },
189
+ {
190
+ name: 'clear',
191
+ alias: 'c',
192
+ type: Boolean,
193
+ description: 'Clear the currently stored config'
135
194
  }
136
195
  ]
137
196
 
@@ -291,6 +350,7 @@ const mainUsageGuide = commandLineUsage([
291
350
  header: i18n.__('constantsCommands'),
292
351
  content: [
293
352
  { name: i18n.__('authName'), summary: i18n.__('helpAuthSummary') },
353
+ { name: i18n.__('scanName'), summary: i18n.__('helpScanSummary') },
294
354
  { name: i18n.__('lambdaName'), summary: i18n.__('helpLambdaSummary') },
295
355
  { name: i18n.__('versionName'), summary: i18n.__('helpVersionSummary') },
296
356
  { name: i18n.__('configName'), summary: i18n.__('helpConfigSummary') },
@@ -298,7 +358,8 @@ const mainUsageGuide = commandLineUsage([
298
358
  ]
299
359
  },
300
360
  {
301
- content: '{underline https://www.contrastsecurity.com}'
361
+ content:
362
+ '{underline https://developer.contrastsecurity.com/} \n For technical support head to {underline https://support.contrastsecurity.com}'
302
363
  }
303
364
  ])
304
365
 
@@ -309,6 +370,8 @@ module.exports = {
309
370
  mainUsageGuide,
310
371
  mainDefinition,
311
372
  scanOptionDefinitions,
312
- auditOptionDefinitions
373
+ auditOptionDefinitions,
374
+ authOptionDefinitions,
375
+ configOptionDefinitions
313
376
  }
314
377
  }