@contrast/contrast 1.0.20 → 1.0.22

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 (53) hide show
  1. package/dist/cliConstants.js +17 -9
  2. package/dist/commands/audit/help.js +5 -1
  3. package/dist/commands/audit/processAudit.js +1 -1
  4. package/dist/commands/auth/auth.js +5 -0
  5. package/dist/commands/fingerprint/fingerprintConfig.js +12 -0
  6. package/dist/commands/fingerprint/processFingerprint.js +14 -0
  7. package/dist/commands/learn/learn.js +9 -0
  8. package/dist/commands/learn/processLearn.js +10 -0
  9. package/dist/common/HTTPClient.js +9 -0
  10. package/dist/common/commonHelp.js +8 -1
  11. package/dist/constants/constants.js +1 -1
  12. package/dist/constants/lambda.js +1 -0
  13. package/dist/constants/locales.js +20 -12
  14. package/dist/index.js +8 -0
  15. package/dist/lambda/help.js +5 -1
  16. package/dist/lambda/scanRequest.js +12 -1
  17. package/dist/scaAnalysis/common/treeUpload.js +3 -0
  18. package/dist/scaAnalysis/javascript/analysis.js +11 -33
  19. package/dist/scaAnalysis/javascript/index.js +14 -1
  20. package/dist/scaAnalysis/javascript/scaServiceParser.js +3 -3
  21. package/dist/scaAnalysis/scaAnalysis.js +155 -0
  22. package/dist/scan/autoDetection.js +2 -2
  23. package/dist/scan/fileUtils.js +2 -2
  24. package/dist/scan/help.js +5 -1
  25. package/dist/utils/settingsHelper.js +2 -2
  26. package/package.json +1 -1
  27. package/src/cliConstants.js +19 -9
  28. package/src/commands/audit/help.js +5 -1
  29. package/src/commands/audit/processAudit.js +1 -1
  30. package/src/commands/auth/auth.js +5 -0
  31. package/src/commands/fingerprint/fingerprintConfig.js +19 -0
  32. package/src/commands/fingerprint/processFingerprint.js +21 -0
  33. package/src/commands/learn/learn.js +10 -0
  34. package/src/commands/learn/processLearn.js +13 -0
  35. package/src/common/HTTPClient.js +11 -0
  36. package/src/common/commonHelp.js +11 -1
  37. package/src/constants/constants.js +1 -1
  38. package/src/constants/lambda.js +1 -0
  39. package/src/constants/locales.js +28 -12
  40. package/src/index.ts +10 -0
  41. package/src/lambda/help.ts +5 -1
  42. package/src/lambda/scanRequest.ts +27 -2
  43. package/src/scaAnalysis/common/treeUpload.js +7 -0
  44. package/src/scaAnalysis/javascript/analysis.js +19 -34
  45. package/src/scaAnalysis/javascript/index.js +29 -1
  46. package/src/scaAnalysis/javascript/scaServiceParser.js +3 -3
  47. package/src/scaAnalysis/scaAnalysis.js +206 -0
  48. package/src/scan/autoDetection.js +2 -2
  49. package/src/scan/fileUtils.js +2 -2
  50. package/src/scan/help.js +5 -1
  51. package/src/utils/settingsHelper.js +2 -2
  52. package/dist/commands/scan/sca/scaAnalysis.js +0 -157
  53. package/src/commands/scan/sca/scaAnalysis.js +0 -211
@@ -14,12 +14,22 @@ import { ApiParams, LambdaOptions } from './lambda'
14
14
  import { log, prettyPrintJson } from './logUtils'
15
15
  import { CliError } from './cliError'
16
16
  import { ERRORS } from './constants'
17
+ import { sleep } from '../utils/requestUtils'
17
18
 
18
- const sendScanPostRequest = async (
19
+ const MAX_RETRIES = 2
20
+
21
+ const sendScanPostRequest: (
19
22
  config: any,
20
23
  params: ApiParams,
21
24
  functionsEvent: unknown,
22
- showProgress = false
25
+ showProgress?: boolean,
26
+ retryNumber?: number
27
+ ) => any = async (
28
+ config,
29
+ params,
30
+ functionsEvent,
31
+ showProgress = false,
32
+ retryNumber = 0
23
33
  ) => {
24
34
  const client = getHttpClient(config)
25
35
 
@@ -50,6 +60,21 @@ const sendScanPostRequest = async (
50
60
  })
51
61
  errorCode = false
52
62
  break
63
+ case 'not_supported_lambda':
64
+ description = i18n.__(errorCode)
65
+ errorCode = false
66
+ break
67
+ default:
68
+ if (retryNumber < MAX_RETRIES) {
69
+ await sleep(3 * 1000)
70
+ return sendScanPostRequest(
71
+ config,
72
+ params,
73
+ functionsEvent,
74
+ showProgress,
75
+ retryNumber + 1
76
+ )
77
+ }
53
78
  }
54
79
 
55
80
  throw new CliError(ERRORS.FAILED_TO_START_SCAN, {
@@ -18,6 +18,13 @@ const commonSendSnapShot = async (analysis, config) => {
18
18
  if (res.statusCode === 201) {
19
19
  return res.body
20
20
  } else {
21
+ if (res.statusCode === 403) {
22
+ throw new Error(
23
+ `🛑 Contrast audit failed \nPlease check you have the right permissions and the application ${
24
+ config.applicationName ? config.applicationName : ''
25
+ } has not been archived.`.replace(/ +(?= )/g, '')
26
+ )
27
+ }
21
28
  throw new Error(res.statusCode + ` error processing dependencies`)
22
29
  }
23
30
  })
@@ -44,48 +44,33 @@ const readYarn = async (config, languageFiles, nameOfFile) => {
44
44
  }
45
45
  }
46
46
 
47
- const parseNpmLockFile = async js => {
47
+ const parseNpmLockFile = async npmLockFile => {
48
48
  try {
49
- js.npmLockFile = JSON.parse(js.rawLockFileContents)
50
- if (js.npmLockFile && js.npmLockFile.lockfileVersion > 1) {
51
- const listOfTopDep = Object.keys(js.npmLockFile.dependencies)
52
- Object.entries(js.npmLockFile.dependencies).forEach(([objKey, value]) => {
53
- if (value.requires) {
54
- const listOfRequiresDep = Object.keys(value.requires)
55
- listOfRequiresDep.forEach(dep => {
56
- if (!listOfTopDep.includes(dep)) {
57
- addDepToLockFile(js, value['requires'], dep)
58
- }
59
- })
60
- }
49
+ if (!npmLockFile.parsedPackages) {
50
+ npmLockFile.parsedPackages = {}
51
+ }
61
52
 
62
- if (value.dependencies) {
63
- Object.entries(value.dependencies).forEach(
64
- ([objChildKey, childValue]) => {
65
- if (childValue.requires) {
66
- const listOfRequiresDep = Object.keys(childValue.requires)
67
- listOfRequiresDep.forEach(dep => {
68
- if (!listOfTopDep.includes(dep)) {
69
- addDepToLockFile(js, childValue['requires'], dep)
70
- }
71
- })
72
- }
73
- }
74
- )
53
+ Object.entries(npmLockFile.packages).forEach(
54
+ ([packageKey, packageValue]) => {
55
+ if (packageKey.includes('node_modules/')) {
56
+ //remove object keys node modules prefixing
57
+ //e.g: node_modules/@aws-amplify/datastore/node_modules/uuid --> @aws-amplify/datastore/uuid
58
+ packageKey = packageKey.replace(/(node_modules\/)+/g, '')
75
59
  }
76
- })
77
- return js.npmLockFile
78
- } else {
79
- return js.npmLockFile
80
- }
60
+
61
+ npmLockFile.parsedPackages[packageKey] = packageValue
62
+ }
63
+ )
64
+
65
+ //remove base project package - unneeded
66
+ delete npmLockFile.parsedPackages['']
67
+
68
+ return npmLockFile
81
69
  } catch (err) {
82
70
  throw new Error(i18n.__('NodeParseNPM') + `${err.message}`)
83
71
  }
84
72
  }
85
73
 
86
- const addDepToLockFile = (js, depObj, key) => {
87
- return (js.npmLockFile.dependencies[key] = { version: depObj[key] })
88
- }
89
74
  const parseYarnLockFile = async js => {
90
75
  try {
91
76
  js.yarn.yarnLockFile = {}
@@ -14,9 +14,11 @@ const jsAnalysis = async (config, languageFiles) => {
14
14
  const buildNodeTree = async (config, files) => {
15
15
  let analysis = await readFiles(config, files)
16
16
  const rawNode = await parseFiles(config, files, analysis)
17
+
17
18
  if (config.experimental) {
18
19
  return scaServiceParser.parseJS(rawNode)
19
20
  }
21
+
20
22
  return formatMessage.createJavaScriptTSMessage(rawNode)
21
23
  }
22
24
 
@@ -44,8 +46,34 @@ const readFiles = async (config, files) => {
44
46
 
45
47
  const parseFiles = async (config, files, js) => {
46
48
  if (files.includes('package-lock.json')) {
47
- js.npmLockFile = await analysis.parseNpmLockFile(js)
49
+ const npmLockFile = JSON.parse(js.rawLockFileContents)
50
+
51
+ const currentLockFileVersion = npmLockFile.lockfileVersion
52
+ const generalRebuildMessage =
53
+ '\nPlease update to Node 16+ & NPM 8+ or 9+ and then rebuild your package files.' +
54
+ '\nMore info here: https://docs.npmjs.com/cli/v9/configuring-npm/package-lock-json'
55
+
56
+ if (currentLockFileVersion === 1) {
57
+ throw new Error(
58
+ `NPM lockfileVersion 1 is no longer supported. \n ${generalRebuildMessage}`
59
+ )
60
+ }
61
+
62
+ if (!currentLockFileVersion || !npmLockFile.packages) {
63
+ throw new Error(
64
+ `package-lock.json needs to be in the NPM v2 or v3 format. \n ${generalRebuildMessage}`
65
+ )
66
+ }
67
+
68
+ if (currentLockFileVersion === 3 && !config.experimental) {
69
+ throw new Error(
70
+ `NPM lockfileVersion 3 is only supported when using the '-e' flag.`
71
+ )
72
+ }
73
+
74
+ js.npmLockFile = await analysis.parseNpmLockFile(npmLockFile)
48
75
  }
76
+
49
77
  if (files.includes('yarn.lock')) {
50
78
  js = await analysis.parseYarnLockFile(js)
51
79
  }
@@ -77,7 +77,7 @@ const chooseLockFile = rawNode => {
77
77
  if (rawNode?.yarn?.yarnLockFile !== undefined) {
78
78
  return { lockFile: rawNode?.yarn?.yarnLockFile?.object, type: 'yarn' }
79
79
  } else if (rawNode.npmLockFile !== undefined) {
80
- return { lockFile: rawNode?.npmLockFile?.dependencies, type: 'npm' }
80
+ return { lockFile: rawNode?.npmLockFile?.parsedPackages, type: 'npm' }
81
81
  } else {
82
82
  return undefined
83
83
  }
@@ -105,9 +105,9 @@ const createChildDependencies = (lockFileDep, currentDep) => {
105
105
 
106
106
  const createNPMChildDependencies = (lockFileDep, currentDep) => {
107
107
  let depArray = []
108
- if (lockFileDep[currentDep]?.requires) {
108
+ if (lockFileDep[currentDep]?.dependencies) {
109
109
  for (const [key, value] of Object.entries(
110
- lockFileDep[currentDep]?.requires
110
+ lockFileDep[currentDep]?.dependencies
111
111
  )) {
112
112
  depArray.push(key)
113
113
  }
@@ -0,0 +1,206 @@
1
+ const {
2
+ supportedLanguages: { JAVA, GO, PYTHON, RUBY, JAVASCRIPT, NODE, PHP, DOTNET }
3
+ } = require('../constants/constants')
4
+ const {
5
+ pollForSnapshotCompletion
6
+ } = require('../audit/languageAnalysisEngine/sendSnapshot')
7
+ const {
8
+ returnOra,
9
+ startSpinner,
10
+ succeedSpinner
11
+ } = require('../utils/oraWrapper')
12
+ const { vulnerabilityReportV2 } = require('../audit/report/reportingFeature')
13
+ const autoDetection = require('../scan/autoDetection')
14
+ const treeUpload = require('./common/treeUpload')
15
+ const auditController = require('../commands/audit/auditController')
16
+ const rootFile = require('../audit/languageAnalysisEngine/getProjectRootFilenames')
17
+ const path = require('path')
18
+ const i18n = require('i18n')
19
+ const auditSave = require('../audit/save')
20
+ const { auditUsageGuide } = require('../commands/audit/help')
21
+ const repoMode = require('./repoMode')
22
+ const { dotNetAnalysis } = require('./dotnet')
23
+ const { goAnalysis } = require('./go/goAnalysis')
24
+ const { phpAnalysis } = require('./php')
25
+ const { rubyAnalysis } = require('./ruby')
26
+ const { pythonAnalysis } = require('./python')
27
+ const javaAnalysis = require('./java')
28
+ const jsAnalysis = require('./javascript')
29
+ const auditReport = require('./common/auditReport')
30
+ const scaUpload = require('./common/scaServicesUpload')
31
+ const settingsHelper = require('../utils/settingsHelper')
32
+ const chalk = require('chalk')
33
+ const saveResults = require('../scan/saveResults')
34
+ const {
35
+ convertGenericToTypedReportModelSca
36
+ } = require('./common/utils/reportUtilsSca')
37
+
38
+ const processSca = async config => {
39
+ //checks to see whether to use old TS / new SCA path
40
+ config = await settingsHelper.getSettings(config)
41
+
42
+ const startTime = performance.now()
43
+ let filesFound
44
+
45
+ if (config.help) {
46
+ console.log(auditUsageGuide)
47
+ process.exit(0)
48
+ }
49
+
50
+ const projectStats = await rootFile.getProjectStats(config.file)
51
+ let pathWithFile = projectStats.isFile()
52
+
53
+ config.fileName = config.file
54
+ config.file = pathWithFile
55
+ ? rootFile.getDirectoryFromPathGiven(config.file).concat('/')
56
+ : config.file
57
+
58
+ filesFound = await autoDetection.autoDetectAuditFilesAndLanguages(config.file)
59
+
60
+ autoDetection.dealWithMultiJava(filesFound)
61
+
62
+ if (filesFound.length > 1 && pathWithFile) {
63
+ filesFound = filesFound.filter(i =>
64
+ Object.values(i)[0].includes(path.basename(config.fileName))
65
+ )
66
+ }
67
+
68
+ // files found looks like [ { javascript: [ Array ] } ]
69
+ //check we have the language and call the right analyser
70
+ let messageToSend = undefined
71
+ if (filesFound.length === 1) {
72
+ switch (Object.keys(filesFound[0])[0]) {
73
+ case JAVA:
74
+ config.language = JAVA
75
+
76
+ if (config.mode === 'repo') {
77
+ try {
78
+ return repoMode.buildRepo(config, filesFound[0])
79
+ } catch (e) {
80
+ throw new Error(
81
+ 'Unable to build in repository mode. Check your project file'
82
+ )
83
+ }
84
+ } else {
85
+ messageToSend = await javaAnalysis.javaAnalysis(config, filesFound[0])
86
+ }
87
+ break
88
+ case JAVASCRIPT:
89
+ messageToSend = await jsAnalysis.jsAnalysis(config, filesFound[0])
90
+ config.language = NODE
91
+ break
92
+ case PYTHON:
93
+ messageToSend = pythonAnalysis(config, filesFound[0])
94
+ config.language = PYTHON
95
+ break
96
+ case RUBY:
97
+ messageToSend = rubyAnalysis(config, filesFound[0])
98
+ config.language = RUBY
99
+ break
100
+ case PHP:
101
+ messageToSend = phpAnalysis(config, filesFound[0])
102
+ config.language = PHP
103
+ break
104
+ case GO:
105
+ messageToSend = goAnalysis(config, filesFound[0])
106
+ config.language = GO
107
+ break
108
+ case DOTNET:
109
+ if (config.experimental) {
110
+ console.log(
111
+ `${chalk.bold(
112
+ '\n.NET project found\n'
113
+ )} Language type is unsupported.`
114
+ )
115
+ return
116
+ } else {
117
+ messageToSend = dotNetAnalysis(config, filesFound[0])
118
+ config.language = DOTNET
119
+ break
120
+ }
121
+ default:
122
+ //something is wrong
123
+ console.log('No supported language detected in project path')
124
+ return
125
+ }
126
+
127
+ if (!config.applicationId) {
128
+ config.applicationId = await auditController.dealWithNoAppId(config)
129
+ }
130
+
131
+ if (config.experimental) {
132
+ console.log('') //empty log for space before spinner
133
+ const reportSpinner = returnOra(i18n.__('auditSCAAnalysisBegins'))
134
+ startSpinner(reportSpinner)
135
+ const { reportArray, reportId } = await scaUpload.scaTreeUpload(
136
+ messageToSend,
137
+ config
138
+ )
139
+
140
+ const reportModelLibraryList =
141
+ convertGenericToTypedReportModelSca(reportArray)
142
+ auditReport.processAuditReport(config, reportModelLibraryList)
143
+ succeedSpinner(reportSpinner, i18n.__('auditSCAAnalysisComplete'))
144
+
145
+ if (config.save !== undefined) {
146
+ await auditSave.auditSave(config, reportId)
147
+ } else {
148
+ console.log('Use contrast audit --save to generate an SBOM')
149
+ }
150
+
151
+ const endTime = performance.now() - startTime
152
+ const scanDurationMs = endTime - startTime
153
+ console.log(
154
+ `----- completed in ${(scanDurationMs / 1000).toFixed(2)}s -----`
155
+ )
156
+ } else {
157
+ console.log('') //empty log for space before spinner
158
+ //send message to TS
159
+ const reportSpinner = returnOra(i18n.__('auditSCAAnalysisBegins'))
160
+ startSpinner(reportSpinner)
161
+ const snapshotResponse = await treeUpload.commonSendSnapShot(
162
+ messageToSend,
163
+ config
164
+ )
165
+
166
+ // poll for completion
167
+ await pollForSnapshotCompletion(
168
+ config,
169
+ snapshotResponse.id,
170
+ reportSpinner
171
+ )
172
+ succeedSpinner(reportSpinner, i18n.__('auditSCAAnalysisComplete'))
173
+
174
+ await vulnerabilityReportV2(config, snapshotResponse.id)
175
+ if (config.save !== undefined) {
176
+ await auditSave.auditSave(config)
177
+ } else {
178
+ console.log('\nUse contrast audit --save to generate an SBOM')
179
+ }
180
+ const endTime = performance.now() - startTime
181
+ const scanDurationMs = endTime - startTime
182
+
183
+ console.log(
184
+ `----- completed in ${(scanDurationMs / 1000).toFixed(2)}s -----`
185
+ )
186
+ }
187
+ } else {
188
+ if (filesFound.length === 0) {
189
+ console.log(i18n.__('languageAnalysisNoLanguage'))
190
+ console.log(i18n.__('languageAnalysisNoLanguageHelpLine'))
191
+ throw new Error()
192
+ } else {
193
+ console.log(chalk.bold(`\nMultiple language files detected \n`))
194
+ filesFound.forEach(file => {
195
+ console.log(`${Object.keys(file)[0]} : `, Object.values(file)[0])
196
+ })
197
+ throw new Error(
198
+ `Please use --file to audit one language only. \nExample: contrast audit --file package-lock.json`
199
+ )
200
+ }
201
+ }
202
+ }
203
+
204
+ module.exports = {
205
+ processSca
206
+ }
@@ -1,8 +1,8 @@
1
1
  const i18n = require('i18n')
2
2
  const fileFinder = require('./fileUtils')
3
3
 
4
- const autoDetectFingerprintInfo = async filePath => {
5
- let complexObj = await fileFinder.findAllFiles(filePath)
4
+ const autoDetectFingerprintInfo = async (filePath, depth) => {
5
+ let complexObj = await fileFinder.findAllFiles(filePath, depth)
6
6
  let result = []
7
7
  let count = 0
8
8
  complexObj.forEach(i => {
@@ -11,7 +11,7 @@ const findFile = async () => {
11
11
  })
12
12
  }
13
13
 
14
- const findAllFiles = async filePath => {
14
+ const findAllFiles = async (filePath, depth = 2) => {
15
15
  const result = await fg(
16
16
  [
17
17
  '**/pom.xml',
@@ -25,7 +25,7 @@ const findAllFiles = async filePath => {
25
25
  ],
26
26
  {
27
27
  dot: false,
28
- deep: 2,
28
+ deep: depth,
29
29
  onlyFiles: true,
30
30
  absolute: true,
31
31
  cwd: filePath ? filePath : process.cwd()
package/src/scan/help.js CHANGED
@@ -4,6 +4,9 @@ const constants = require('../cliConstants')
4
4
  const { commonHelpLinks } = require('../common/commonHelp')
5
5
 
6
6
  const scanUsageGuide = commandLineUsage([
7
+ {
8
+ header: i18n.__('constantsHeader')
9
+ },
7
10
  {
8
11
  header: i18n.__('scanHeader')
9
12
  },
@@ -44,7 +47,8 @@ const scanUsageGuide = commandLineUsage([
44
47
  constants.commandLineDefinitions.scanAdvancedOptionDefinitionsForHelp
45
48
  },
46
49
  commonHelpLinks()[0],
47
- commonHelpLinks()[1]
50
+ commonHelpLinks()[1],
51
+ commonHelpLinks()[2]
48
52
  ])
49
53
 
50
54
  module.exports = {
@@ -12,9 +12,9 @@ const getSettings = async config => {
12
12
  const isSCAServicesAvailable = async config => {
13
13
  const client = commonApi.getHttpClient(config)
14
14
  return client
15
- .scaServiceIngests(config)
15
+ .scaServiceHealth(config)
16
16
  .then(res => {
17
- return res.statusCode !== 403
17
+ return res.body.status === 'UP'
18
18
  })
19
19
  .catch(err => {
20
20
  console.log(err)
@@ -1,157 +0,0 @@
1
- "use strict";
2
- const { supportedLanguages: { JAVA, GO, PYTHON, RUBY, JAVASCRIPT, NODE, PHP, DOTNET } } = require('../../../constants/constants');
3
- const { pollForSnapshotCompletion } = require('../../../audit/languageAnalysisEngine/sendSnapshot');
4
- const { returnOra, startSpinner, succeedSpinner } = require('../../../utils/oraWrapper');
5
- const { vulnerabilityReportV2 } = require('../../../audit/report/reportingFeature');
6
- const autoDetection = require('../../../scan/autoDetection');
7
- const treeUpload = require('../../../scaAnalysis/common/treeUpload');
8
- const auditController = require('../../audit/auditController');
9
- const rootFile = require('../../../audit/languageAnalysisEngine/getProjectRootFilenames');
10
- const path = require('path');
11
- const i18n = require('i18n');
12
- const auditSave = require('../../../audit/save');
13
- const { auditUsageGuide } = require('../../audit/help');
14
- const repoMode = require('../../../scaAnalysis/repoMode/index');
15
- const { dotNetAnalysis } = require('../../../scaAnalysis/dotnet');
16
- const { goAnalysis } = require('../../../scaAnalysis/go/goAnalysis');
17
- const { phpAnalysis } = require('../../../scaAnalysis/php/index');
18
- const { rubyAnalysis } = require('../../../scaAnalysis/ruby');
19
- const { pythonAnalysis } = require('../../../scaAnalysis/python');
20
- const javaAnalysis = require('../../../scaAnalysis/java');
21
- const jsAnalysis = require('../../../scaAnalysis/javascript');
22
- const auditReport = require('../../../scaAnalysis/common/auditReport');
23
- const scaUpload = require('../../../scaAnalysis/common/scaServicesUpload');
24
- const settingsHelper = require('../../../utils/settingsHelper');
25
- const chalk = require('chalk');
26
- const saveResults = require('../../../scan/saveResults');
27
- const { convertGenericToTypedReportModelSca } = require('../../../scaAnalysis/common/utils/reportUtilsSca');
28
- const processSca = async (config) => {
29
- config = await settingsHelper.getSettings(config);
30
- const startTime = performance.now();
31
- let filesFound;
32
- if (config.help) {
33
- console.log(auditUsageGuide);
34
- process.exit(0);
35
- }
36
- const projectStats = await rootFile.getProjectStats(config.file);
37
- let pathWithFile = projectStats.isFile();
38
- config.fileName = config.file;
39
- config.file = pathWithFile
40
- ? rootFile.getDirectoryFromPathGiven(config.file).concat('/')
41
- : config.file;
42
- if (config.fingerprint && config.experimental) {
43
- let fingerprint = await autoDetection.autoDetectFingerprintInfo(config.file);
44
- let idArray = fingerprint.map(x => x.id);
45
- await saveResults.writeResultsToFile(fingerprint, 'fingerPrintInfo.json');
46
- console.log(idArray);
47
- }
48
- else {
49
- filesFound = await autoDetection.autoDetectAuditFilesAndLanguages(config.file);
50
- autoDetection.dealWithMultiJava(filesFound);
51
- if (filesFound.length > 1 && pathWithFile) {
52
- filesFound = filesFound.filter(i => Object.values(i)[0].includes(path.basename(config.fileName)));
53
- }
54
- let messageToSend = undefined;
55
- if (filesFound.length === 1) {
56
- switch (Object.keys(filesFound[0])[0]) {
57
- case JAVA:
58
- config.language = JAVA;
59
- if (config.mode === 'repo') {
60
- try {
61
- return repoMode.buildRepo(config, filesFound[0]);
62
- }
63
- catch (e) {
64
- throw new Error('Unable to build in repository mode. Check your project file');
65
- }
66
- }
67
- else {
68
- messageToSend = await javaAnalysis.javaAnalysis(config, filesFound[0]);
69
- }
70
- break;
71
- case JAVASCRIPT:
72
- messageToSend = await jsAnalysis.jsAnalysis(config, filesFound[0]);
73
- config.language = NODE;
74
- break;
75
- case PYTHON:
76
- messageToSend = pythonAnalysis(config, filesFound[0]);
77
- config.language = PYTHON;
78
- break;
79
- case RUBY:
80
- messageToSend = rubyAnalysis(config, filesFound[0]);
81
- config.language = RUBY;
82
- break;
83
- case PHP:
84
- messageToSend = phpAnalysis(config, filesFound[0]);
85
- config.language = PHP;
86
- break;
87
- case GO:
88
- messageToSend = goAnalysis(config, filesFound[0]);
89
- config.language = GO;
90
- break;
91
- case DOTNET:
92
- messageToSend = dotNetAnalysis(config, filesFound[0]);
93
- config.language = DOTNET;
94
- break;
95
- default:
96
- console.log('No supported language detected in project path');
97
- return;
98
- }
99
- if (!config.applicationId) {
100
- config.applicationId = await auditController.dealWithNoAppId(config);
101
- }
102
- if (config.experimental) {
103
- console.log('');
104
- const reportSpinner = returnOra(i18n.__('auditSCAAnalysisBegins'));
105
- startSpinner(reportSpinner);
106
- const { reportArray, reportId } = await scaUpload.scaTreeUpload(messageToSend, config);
107
- const reportModelLibraryList = convertGenericToTypedReportModelSca(reportArray);
108
- auditReport.processAuditReport(config, reportModelLibraryList);
109
- succeedSpinner(reportSpinner, i18n.__('auditSCAAnalysisComplete'));
110
- if (config.save !== undefined) {
111
- await auditSave.auditSave(config, reportId);
112
- }
113
- else {
114
- console.log('Use contrast audit --save to generate an SBOM');
115
- }
116
- const endTime = performance.now() - startTime;
117
- const scanDurationMs = endTime - startTime;
118
- console.log(`----- completed in ${(scanDurationMs / 1000).toFixed(2)}s -----`);
119
- }
120
- else {
121
- console.log('');
122
- const reportSpinner = returnOra(i18n.__('auditSCAAnalysisBegins'));
123
- startSpinner(reportSpinner);
124
- const snapshotResponse = await treeUpload.commonSendSnapShot(messageToSend, config);
125
- await pollForSnapshotCompletion(config, snapshotResponse.id, reportSpinner);
126
- succeedSpinner(reportSpinner, i18n.__('auditSCAAnalysisComplete'));
127
- await vulnerabilityReportV2(config, snapshotResponse.id);
128
- if (config.save !== undefined) {
129
- await auditSave.auditSave(config);
130
- }
131
- else {
132
- console.log('\nUse contrast audit --save to generate an SBOM');
133
- }
134
- const endTime = performance.now() - startTime;
135
- const scanDurationMs = endTime - startTime;
136
- console.log(`----- completed in ${(scanDurationMs / 1000).toFixed(2)}s -----`);
137
- }
138
- }
139
- else {
140
- if (filesFound.length === 0) {
141
- console.log(i18n.__('languageAnalysisNoLanguage'));
142
- console.log(i18n.__('languageAnalysisNoLanguageHelpLine'));
143
- throw new Error();
144
- }
145
- else {
146
- console.log(chalk.bold(`\nMultiple language files detected \n`));
147
- filesFound.forEach(file => {
148
- console.log(`${Object.keys(file)[0]} : `, Object.values(file)[0]);
149
- });
150
- throw new Error(`Please use --file to audit one language only. \nExample: contrast audit --file package-lock.json`);
151
- }
152
- }
153
- }
154
- };
155
- module.exports = {
156
- processSca
157
- };