@contrast/contrast 1.0.16 → 1.0.18

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 (61) hide show
  1. package/dist/audit/catalogueApplication/catalogueApplication.js +1 -1
  2. package/dist/cliConstants.js +91 -109
  3. package/dist/commands/audit/auditConfig.js +10 -12
  4. package/dist/commands/audit/auditController.js +12 -16
  5. package/dist/commands/audit/help.js +32 -26
  6. package/dist/commands/audit/processAudit.js +16 -22
  7. package/dist/commands/audit/saveFile.js +3 -9
  8. package/dist/commands/scan/processScan.js +5 -7
  9. package/dist/commands/scan/sca/scaAnalysis.js +105 -88
  10. package/dist/common/HTTPClient.js +1 -1
  11. package/dist/common/commonHelp.js +35 -17
  12. package/dist/common/errorHandling.js +38 -57
  13. package/dist/common/versionChecker.js +24 -27
  14. package/dist/constants/constants.js +1 -1
  15. package/dist/constants/locales.js +20 -91
  16. package/dist/lambda/help.js +2 -1
  17. package/dist/lambda/lambda.js +2 -7
  18. package/dist/scaAnalysis/java/analysis.js +40 -5
  19. package/dist/scaAnalysis/java/index.js +14 -2
  20. package/dist/scan/autoDetection.js +26 -3
  21. package/dist/scan/fileUtils.js +24 -1
  22. package/dist/scan/help.js +11 -4
  23. package/dist/scan/saveResults.js +1 -1
  24. package/dist/utils/commonApi.js +16 -1
  25. package/dist/utils/generalAPI.js +1 -2
  26. package/dist/utils/paramsUtil/configStoreParams.js +12 -1
  27. package/dist/utils/paramsUtil/paramHandler.js +7 -1
  28. package/dist/utils/saveFile.js +2 -1
  29. package/package.json +2 -1
  30. package/src/audit/catalogueApplication/catalogueApplication.js +1 -1
  31. package/src/cliConstants.js +96 -116
  32. package/src/commands/audit/auditConfig.js +19 -0
  33. package/src/commands/audit/{auditController.ts → auditController.js} +17 -12
  34. package/src/commands/audit/{help.ts → help.js} +19 -7
  35. package/src/commands/audit/processAudit.js +37 -0
  36. package/src/commands/audit/{saveFile.ts → saveFile.js} +2 -2
  37. package/src/commands/scan/processScan.js +4 -10
  38. package/src/commands/scan/sca/scaAnalysis.js +135 -115
  39. package/src/common/HTTPClient.js +1 -1
  40. package/src/common/commonHelp.js +43 -0
  41. package/src/common/{errorHandling.ts → errorHandling.js} +25 -32
  42. package/src/common/{versionChecker.ts → versionChecker.js} +15 -10
  43. package/src/constants/constants.js +1 -1
  44. package/src/constants/locales.js +23 -129
  45. package/src/lambda/help.ts +2 -1
  46. package/src/lambda/lambda.ts +2 -10
  47. package/src/scaAnalysis/java/analysis.js +43 -10
  48. package/src/scaAnalysis/java/index.js +19 -2
  49. package/src/scan/autoDetection.js +34 -3
  50. package/src/scan/fileUtils.js +29 -1
  51. package/src/scan/help.js +12 -4
  52. package/src/scan/saveResults.js +1 -1
  53. package/src/utils/commonApi.js +19 -1
  54. package/src/utils/generalAPI.js +1 -2
  55. package/src/utils/getConfig.ts +1 -0
  56. package/src/utils/paramsUtil/configStoreParams.js +14 -1
  57. package/src/utils/paramsUtil/paramHandler.js +9 -1
  58. package/src/utils/saveFile.js +2 -1
  59. package/src/commands/audit/auditConfig.ts +0 -21
  60. package/src/commands/audit/processAudit.ts +0 -40
  61. package/src/common/commonHelp.ts +0 -13
@@ -20,7 +20,7 @@ const path = require('path')
20
20
  const i18n = require('i18n')
21
21
  const auditSave = require('../../../audit/save')
22
22
  const { auditUsageGuide } = require('../../audit/help')
23
- const { buildRepo } = require('../../../scaAnalysis/repoMode/index')
23
+ const repoMode = require('../../../scaAnalysis/repoMode/index')
24
24
  const { dotNetAnalysis } = require('../../../scaAnalysis/dotnet')
25
25
  const { goAnalysis } = require('../../../scaAnalysis/go/goAnalysis')
26
26
  const { phpAnalysis } = require('../../../scaAnalysis/php/index')
@@ -32,6 +32,7 @@ const auditReport = require('../../../scaAnalysis/common/auditReport')
32
32
  const scaUpload = require('../../../scaAnalysis/common/scaServicesUpload')
33
33
  const settingsHelper = require('../../../utils/settingsHelper')
34
34
  const chalk = require('chalk')
35
+ const saveResults = require('../../../scan/saveResults')
35
36
 
36
37
  const processSca = async config => {
37
38
  //checks to see whether to use old TS / new SCA path
@@ -53,130 +54,149 @@ const processSca = async config => {
53
54
  ? rootFile.getDirectoryFromPathGiven(config.file).concat('/')
54
55
  : config.file
55
56
 
56
- filesFound = await autoDetection.autoDetectAuditFilesAndLanguages(config.file)
57
-
58
- if (filesFound.length > 1 && pathWithFile) {
59
- filesFound = filesFound.filter(i =>
60
- Object.values(i)[0].includes(path.basename(config.fileName))
57
+ if (config.fingerprint && config.experimental) {
58
+ let fingerprint = await autoDetection.autoDetectFingerprintInfo(config.file)
59
+ let idArray = fingerprint.map(x => x.id)
60
+ await saveResults.writeResultsToFile(fingerprint, 'fingerPrintInfo.json')
61
+ console.log(idArray)
62
+ } else {
63
+ filesFound = await autoDetection.autoDetectAuditFilesAndLanguages(
64
+ config.file
61
65
  )
62
- }
63
-
64
- // files found looks like [ { javascript: [ Array ] } ]
65
- //check we have the language and call the right analyser
66
- //refactor new analyser and see if we can clean it up
67
- if (config.mode === 'repo') {
68
- try {
69
- return buildRepo(config, filesFound[0])
70
- } catch (e) {
71
- console.log('Unable to build in repository mode. Check your project file')
72
- process.exit(0)
73
- }
74
- }
75
66
 
76
- let messageToSend = undefined
77
- if (filesFound.length === 1) {
78
- switch (Object.keys(filesFound[0])[0]) {
79
- case JAVA:
80
- messageToSend = javaAnalysis.javaAnalysis(config, filesFound[0])
81
- config.language = JAVA
82
- break
83
- case JAVASCRIPT:
84
- messageToSend = await jsAnalysis.jsAnalysis(config, filesFound[0])
85
- config.language = NODE
86
- break
87
- case PYTHON:
88
- messageToSend = pythonAnalysis(config, filesFound[0])
89
- config.language = PYTHON
90
- break
91
- case RUBY:
92
- messageToSend = rubyAnalysis(config, filesFound[0])
93
- config.language = RUBY
94
- break
95
- case PHP:
96
- messageToSend = phpAnalysis(config, filesFound[0])
97
- config.language = PHP
98
- break
99
- case GO:
100
- messageToSend = goAnalysis(config, filesFound[0])
101
- config.language = GO
102
- break
103
- case DOTNET:
104
- messageToSend = dotNetAnalysis(config, filesFound[0])
105
- config.language = DOTNET
106
- break
107
- default:
108
- //something is wrong
109
- console.log('No supported language detected in project path')
110
- return
111
- }
112
-
113
- if (!config.applicationId) {
114
- config.applicationId = await auditController.dealWithNoAppId(config)
115
- }
67
+ autoDetection.dealWithMultiJava(filesFound)
116
68
 
117
- if (config.experimental) {
118
- console.log('') //empty log for space before spinner
119
- const reportSpinner = returnOra(i18n.__('auditSCAAnalysisBegins'))
120
- startSpinner(reportSpinner)
121
- const [reports, reportId] = await scaUpload.scaTreeUpload(
122
- messageToSend,
123
- config
69
+ if (filesFound.length > 1 && pathWithFile) {
70
+ filesFound = filesFound.filter(i =>
71
+ Object.values(i)[0].includes(path.basename(config.fileName))
124
72
  )
73
+ }
125
74
 
126
- auditReport.processAuditReport(config, reports[0])
127
- succeedSpinner(reportSpinner, i18n.__('auditSCAAnalysisComplete'))
128
-
129
- if (config.save !== undefined) {
130
- await auditSave.auditSave(config, reportId)
75
+ // files found looks like [ { javascript: [ Array ] } ]
76
+ //check we have the language and call the right analyser
77
+ let messageToSend = undefined
78
+ if (filesFound.length === 1) {
79
+ switch (Object.keys(filesFound[0])[0]) {
80
+ case JAVA:
81
+ config.language = JAVA
82
+
83
+ if (config.mode === 'repo') {
84
+ try {
85
+ return repoMode.buildRepo(config, filesFound[0])
86
+ } catch (e) {
87
+ throw new Error(
88
+ 'Unable to build in repository mode. Check your project file'
89
+ )
90
+ }
91
+ } else {
92
+ messageToSend = await javaAnalysis.javaAnalysis(
93
+ config,
94
+ filesFound[0]
95
+ )
96
+ }
97
+ break
98
+ case JAVASCRIPT:
99
+ messageToSend = await jsAnalysis.jsAnalysis(config, filesFound[0])
100
+ config.language = NODE
101
+ break
102
+ case PYTHON:
103
+ messageToSend = pythonAnalysis(config, filesFound[0])
104
+ config.language = PYTHON
105
+ break
106
+ case RUBY:
107
+ messageToSend = rubyAnalysis(config, filesFound[0])
108
+ config.language = RUBY
109
+ break
110
+ case PHP:
111
+ messageToSend = phpAnalysis(config, filesFound[0])
112
+ config.language = PHP
113
+ break
114
+ case GO:
115
+ messageToSend = goAnalysis(config, filesFound[0])
116
+ config.language = GO
117
+ break
118
+ case DOTNET:
119
+ messageToSend = dotNetAnalysis(config, filesFound[0])
120
+ config.language = DOTNET
121
+ break
122
+ default:
123
+ //something is wrong
124
+ console.log('No supported language detected in project path')
125
+ return
131
126
  }
132
127
 
133
- const endTime = performance.now() - startTime
134
- const scanDurationMs = endTime - startTime
135
- console.log(
136
- `----- completed in ${(scanDurationMs / 1000).toFixed(2)}s -----`
137
- )
138
- } else {
139
- console.log('') //empty log for space before spinner
140
- //send message to TS
141
- const reportSpinner = returnOra(i18n.__('auditSCAAnalysisBegins'))
142
- startSpinner(reportSpinner)
143
- const snapshotResponse = await treeUpload.commonSendSnapShot(
144
- messageToSend,
145
- config
146
- )
147
-
148
- // poll for completion
149
- await pollForSnapshotCompletion(
150
- config,
151
- snapshotResponse.id,
152
- reportSpinner
153
- )
154
- succeedSpinner(reportSpinner, i18n.__('auditSCAAnalysisComplete'))
155
-
156
- await vulnerabilityReportV2(config, snapshotResponse.id)
157
- if (config.save !== undefined) {
158
- await auditSave.auditSave(config)
128
+ if (!config.applicationId) {
129
+ config.applicationId = await auditController.dealWithNoAppId(config)
159
130
  }
160
- const endTime = performance.now() - startTime
161
- const scanDurationMs = endTime - startTime
162
131
 
163
- console.log(
164
- `----- completed in ${(scanDurationMs / 1000).toFixed(2)}s -----`
165
- )
166
- }
167
- } else {
168
- if (filesFound.length === 0) {
169
- console.log(i18n.__('languageAnalysisNoLanguage'))
170
- console.log(i18n.__('languageAnalysisNoLanguageHelpLine'))
171
- throw new Error()
132
+ if (config.experimental) {
133
+ console.log('') //empty log for space before spinner
134
+ const reportSpinner = returnOra(i18n.__('auditSCAAnalysisBegins'))
135
+ startSpinner(reportSpinner)
136
+ const [reports, reportId] = await scaUpload.scaTreeUpload(
137
+ messageToSend,
138
+ config
139
+ )
140
+
141
+ auditReport.processAuditReport(config, reports[0])
142
+ succeedSpinner(reportSpinner, i18n.__('auditSCAAnalysisComplete'))
143
+
144
+ if (config.save !== undefined) {
145
+ await auditSave.auditSave(config, reportId)
146
+ } else {
147
+ console.log('Use contrast audit --save to generate an SBOM')
148
+ }
149
+
150
+ const endTime = performance.now() - startTime
151
+ const scanDurationMs = endTime - startTime
152
+ console.log(
153
+ `----- completed in ${(scanDurationMs / 1000).toFixed(2)}s -----`
154
+ )
155
+ } else {
156
+ console.log('') //empty log for space before spinner
157
+ //send message to TS
158
+ const reportSpinner = returnOra(i18n.__('auditSCAAnalysisBegins'))
159
+ startSpinner(reportSpinner)
160
+ const snapshotResponse = await treeUpload.commonSendSnapShot(
161
+ messageToSend,
162
+ config
163
+ )
164
+
165
+ // poll for completion
166
+ await pollForSnapshotCompletion(
167
+ config,
168
+ snapshotResponse.id,
169
+ reportSpinner
170
+ )
171
+ succeedSpinner(reportSpinner, i18n.__('auditSCAAnalysisComplete'))
172
+
173
+ await vulnerabilityReportV2(config, snapshotResponse.id)
174
+ if (config.save !== undefined) {
175
+ await auditSave.auditSave(config)
176
+ } else {
177
+ console.log('\nUse contrast audit --save to generate an SBOM')
178
+ }
179
+ const endTime = performance.now() - startTime
180
+ const scanDurationMs = endTime - startTime
181
+
182
+ console.log(
183
+ `----- completed in ${(scanDurationMs / 1000).toFixed(2)}s -----`
184
+ )
185
+ }
172
186
  } else {
173
- console.log(chalk.bold(`\nMultiple language files detected \n`))
174
- filesFound.forEach(file => {
175
- console.log(`${Object.keys(file)[0]} : `, Object.values(file)[0])
176
- })
177
- throw new Error(
178
- `Please use --file to audit one language only. \nExample: contrast audit --file package-lock.json`
179
- )
187
+ if (filesFound.length === 0) {
188
+ console.log(i18n.__('languageAnalysisNoLanguage'))
189
+ console.log(i18n.__('languageAnalysisNoLanguageHelpLine'))
190
+ throw new Error()
191
+ } else {
192
+ console.log(chalk.bold(`\nMultiple language files detected \n`))
193
+ filesFound.forEach(file => {
194
+ console.log(`${Object.keys(file)[0]} : `, Object.values(file)[0])
195
+ })
196
+ throw new Error(
197
+ `Please use --file to audit one language only. \nExample: contrast audit --file package-lock.json`
198
+ )
199
+ }
180
200
  }
181
201
  }
182
202
  }
@@ -6,7 +6,7 @@ const { AUTH_CALLBACK_URL } = require('../constants/constants')
6
6
  function HTTPClient(config) {
7
7
  const apiKey = config.apiKey
8
8
  const authToken = config.authorization
9
- this.rejectUnauthorized = !config.ignoreCertErrors
9
+ this.rejectUnauthorized = !config.certSelfSigned
10
10
 
11
11
  const superApiKey = config.superApiKey
12
12
  const superAuthToken = config.superAuthorization
@@ -0,0 +1,43 @@
1
+ const i18n = require('i18n')
2
+ const chalk = require('chalk')
3
+
4
+ const commonHelpLinks = () => {
5
+ return [
6
+ {
7
+ header: i18n.__('commonHelpHeader'),
8
+ content: [
9
+ i18n.__('commonHelpCheckOutHeader') + i18n.__('commonHelpCheckOutText'),
10
+ i18n.__('commonHelpLearnMoreHeader') +
11
+ i18n.__('commonHelpLearnMoreText'),
12
+ i18n.__('commonHelpJoinDiscussionHeader') +
13
+ i18n.__('commonHelpJoinDiscussionText')
14
+ ]
15
+ },
16
+ {
17
+ header: i18n.__('commonHelpEnterpriseHeader'),
18
+ content: [
19
+ i18n.__('commonHelpLearnMoreEnterpriseHeader') +
20
+ i18n.__('commonHelpLearnMoreEnterpriseText')
21
+ ]
22
+ }
23
+ ]
24
+ }
25
+
26
+ const postRunMessage = commandName => {
27
+ console.log('\n' + chalk.underline.bold('Other Features:'))
28
+ if (commandName !== 'scan')
29
+ console.log(
30
+ "'contrast scan' to run Contrasts’ industry leading SAST scanner"
31
+ )
32
+ if (commandName !== 'audit')
33
+ console.log(
34
+ "'contrast audit' to find vulnerabilities in your open source dependencies"
35
+ )
36
+ if (commandName !== 'lambda')
37
+ console.log("'contrast lambda' to secure your AWS serverless functions")
38
+ }
39
+
40
+ module.exports = {
41
+ commonHelpLinks,
42
+ postRunMessage
43
+ }
@@ -1,26 +1,4 @@
1
- import i18n from 'i18n'
2
-
3
- const handleResponseErrors = (res: any, api: string) => {
4
- if (res.statusCode === 400) {
5
- api === 'catalogue' ? badRequestError(true) : badRequestError(false)
6
- } else if (res.statusCode === 401) {
7
- unauthenticatedError()
8
- } else if (res.statusCode === 403) {
9
- forbiddenError()
10
- } else if (res.statusCode === 407) {
11
- proxyError()
12
- } else {
13
- if (api === 'snapshot' || api === 'catalogue') {
14
- snapshotFailureError()
15
- }
16
- if (api === 'vulnerabilities') {
17
- vulnerabilitiesFailureError()
18
- }
19
- if (api === 'report') {
20
- reportFailureError()
21
- }
22
- }
23
- }
1
+ const i18n = require('i18n')
24
2
 
25
3
  const libraryAnalysisError = () => {
26
4
  console.log(i18n.__('libraryAnalysisError'))
@@ -47,7 +25,7 @@ const unauthenticatedError = () => {
47
25
  generalError('unauthenticatedErrorHeader', 'unauthenticatedErrorMessage')
48
26
  }
49
27
 
50
- const badRequestError = (catalogue: boolean) => {
28
+ const badRequestError = catalogue => {
51
29
  catalogue === true
52
30
  ? generalError('badRequestErrorHeader', 'badRequestCatalogueErrorMessage')
53
31
  : generalError('badRequestErrorHeader', 'badRequestErrorMessage')
@@ -70,6 +48,22 @@ const maxAppError = () => {
70
48
  process.exit(1)
71
49
  }
72
50
 
51
+ const parametersError = () => {
52
+ generalError(
53
+ `Values not recognised`,
54
+ 'Check your command & keys again for hidden characters.\nFor more information use contrast help.'
55
+ )
56
+ process.exit(1)
57
+ }
58
+
59
+ const invalidHostNameError = () => {
60
+ generalError(
61
+ `Invalid host`,
62
+ 'Check that the host parameter does not include a trailing "/".'
63
+ )
64
+ process.exit(1)
65
+ }
66
+
73
67
  const failOptionError = () => {
74
68
  console.log(
75
69
  '\n ******************************** ' +
@@ -86,7 +80,7 @@ const failOptionError = () => {
86
80
  * @param message message for the error
87
81
  * @returns error in general format
88
82
  */
89
- const getErrorMessage = (header: string, message?: string) => {
83
+ const getErrorMessage = (header, message) => {
90
84
  // prettier-ignore
91
85
  const title = `******************************** ${i18n.__(header)} ********************************`
92
86
  const multiLine = message?.includes('\n')
@@ -102,12 +96,12 @@ const getErrorMessage = (header: string, message?: string) => {
102
96
  return `${title}${finalMessage}`
103
97
  }
104
98
 
105
- const generalError = (header: string, message?: string) => {
99
+ const generalError = (header, message) => {
106
100
  const finalMessage = getErrorMessage(header, message)
107
101
  console.log(finalMessage)
108
102
  }
109
103
 
110
- const findCommandOnError = (unknownOptions: string[]) => {
104
+ const findCommandOnError = unknownOptions => {
111
105
  const commandKeywords = {
112
106
  auth: 'auth',
113
107
  audit: 'audit',
@@ -117,13 +111,11 @@ const findCommandOnError = (unknownOptions: string[]) => {
117
111
  }
118
112
 
119
113
  const containsCommandKeyword = unknownOptions.some(
120
- // @ts-ignore
121
114
  command => commandKeywords[command]
122
115
  )
123
116
 
124
117
  if (containsCommandKeyword) {
125
118
  const foundCommands = unknownOptions.filter(
126
- // @ts-ignore
127
119
  command => commandKeywords[command]
128
120
  )
129
121
 
@@ -132,7 +124,7 @@ const findCommandOnError = (unknownOptions: string[]) => {
132
124
  }
133
125
  }
134
126
 
135
- export {
127
+ module.exports = {
136
128
  genericError,
137
129
  unauthenticatedError,
138
130
  badRequestError,
@@ -141,11 +133,12 @@ export {
141
133
  failOptionError,
142
134
  generalError,
143
135
  getErrorMessage,
144
- handleResponseErrors,
145
136
  libraryAnalysisError,
146
137
  findCommandOnError,
147
138
  snapshotFailureError,
148
139
  vulnerabilitiesFailureError,
149
140
  reportFailureError,
150
- maxAppError
141
+ maxAppError,
142
+ parametersError,
143
+ invalidHostNameError
151
144
  }
@@ -1,12 +1,11 @@
1
- import { APP_VERSION } from '../constants/constants'
2
- import boxen from 'boxen'
3
- import chalk from 'chalk'
4
- import semver from 'semver'
5
- import commonApi from '../utils/commonApi'
6
- import { constants } from 'http2'
7
- import { ContrastConf } from '../utils/getConfig'
1
+ const { APP_VERSION } = require('../constants/constants')
2
+ const boxen = require('boxen')
3
+ const chalk = require('chalk')
4
+ const semver = require('semver')
5
+ const commonApi = require('../utils/commonApi')
6
+ const { constants } = require('http2')
8
7
 
9
- export const getLatestVersion = async (config: ContrastConf) => {
8
+ const getLatestVersion = async config => {
10
9
  const client = commonApi.getHttpClient(config)
11
10
  try {
12
11
  const res = await client.getLatestVersion()
@@ -18,7 +17,7 @@ export const getLatestVersion = async (config: ContrastConf) => {
18
17
  }
19
18
  }
20
19
 
21
- export async function findLatestCLIVersion(config: ContrastConf) {
20
+ const findLatestCLIVersion = async config => {
22
21
  const isCI = process.env.CONTRAST_CODESEC_CI
23
22
  ? JSON.parse(process.env.CONTRAST_CODESEC_CI.toLowerCase())
24
23
  : false
@@ -65,6 +64,12 @@ export async function findLatestCLIVersion(config: ContrastConf) {
65
64
  }
66
65
  }
67
66
 
68
- export async function isCorrectNodeVersion(currentVersion: string) {
67
+ const isCorrectNodeVersion = async currentVersion => {
69
68
  return semver.satisfies(currentVersion, '>=16')
70
69
  }
70
+
71
+ module.exports = {
72
+ getLatestVersion,
73
+ findLatestCLIVersion,
74
+ isCorrectNodeVersion
75
+ }
@@ -14,7 +14,7 @@ const HIGH = 'HIGH'
14
14
  const CRITICAL = 'CRITICAL'
15
15
  // App
16
16
  const APP_NAME = 'contrast'
17
- const APP_VERSION = '1.0.16'
17
+ const APP_VERSION = '1.0.18'
18
18
  const TIMEOUT = 120000
19
19
  const HIGH_COLOUR = '#ff9900'
20
20
  const CRITICAL_COLOUR = '#e35858'