@contrast/contrast 1.0.7 → 1.0.8

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 (79) hide show
  1. package/dist/audit/autodetection/autoDetectLanguage.js +3 -3
  2. package/dist/audit/catalogueApplication/catalogueApplication.js +23 -5
  3. package/dist/audit/languageAnalysisEngine/getIdentifiedLanguageInfo.js +5 -5
  4. package/dist/audit/languageAnalysisEngine/getProjectRootFilenames.js +9 -9
  5. package/dist/audit/languageAnalysisEngine/index.js +2 -2
  6. package/dist/audit/languageAnalysisEngine/languageAnalysisFactory.js +5 -28
  7. package/dist/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +11 -4
  8. package/dist/audit/languageAnalysisEngine/report/commonReportingFunctions.js +39 -13
  9. package/dist/audit/languageAnalysisEngine/report/models/reportListModel.js +2 -1
  10. package/dist/audit/languageAnalysisEngine/report/models/severityCountModel.js +3 -0
  11. package/dist/audit/languageAnalysisEngine/report/reportingFeature.js +35 -14
  12. package/dist/audit/languageAnalysisEngine/report/utils/reportUtils.js +3 -3
  13. package/dist/audit/save.js +29 -0
  14. package/dist/commands/audit/auditController.js +21 -5
  15. package/dist/commands/audit/help.js +24 -1
  16. package/dist/commands/audit/processAudit.js +7 -1
  17. package/dist/commands/audit/saveFile.js +7 -3
  18. package/dist/commands/scan/sca/scaAnalysis.js +31 -10
  19. package/dist/common/HTTPClient.js +6 -0
  20. package/dist/common/versionChecker.js +19 -4
  21. package/dist/constants/constants.js +1 -1
  22. package/dist/constants/locales.js +12 -11
  23. package/dist/constants.js +9 -4
  24. package/dist/index.js +4 -3
  25. package/dist/sbom/generateSbom.js +4 -3
  26. package/dist/scaAnalysis/common/formatMessage.js +26 -5
  27. package/dist/scaAnalysis/common/treeUpload.js +0 -1
  28. package/dist/scaAnalysis/go/goReadDepFile.js +1 -3
  29. package/dist/scaAnalysis/java/analysis.js +5 -5
  30. package/dist/scaAnalysis/javascript/analysis.js +110 -0
  31. package/dist/scaAnalysis/javascript/index.js +41 -0
  32. package/dist/scaAnalysis/php/analysis.js +89 -0
  33. package/dist/scaAnalysis/php/index.js +10 -0
  34. package/dist/scaAnalysis/python/analysis.js +8 -7
  35. package/dist/scaAnalysis/ruby/analysis.js +8 -8
  36. package/dist/scaAnalysis/ruby/index.js +2 -2
  37. package/dist/scan/autoDetection.js +4 -4
  38. package/dist/scan/fileUtils.js +13 -2
  39. package/dist/utils/filterProjectPath.js +7 -2
  40. package/package.json +3 -3
  41. package/src/audit/autodetection/autoDetectLanguage.ts +3 -3
  42. package/src/audit/catalogueApplication/catalogueApplication.js +28 -6
  43. package/src/audit/languageAnalysisEngine/getIdentifiedLanguageInfo.js +5 -5
  44. package/src/audit/languageAnalysisEngine/getProjectRootFilenames.js +11 -11
  45. package/src/audit/languageAnalysisEngine/index.js +2 -2
  46. package/src/audit/languageAnalysisEngine/languageAnalysisFactory.js +4 -32
  47. package/src/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +20 -19
  48. package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.ts +67 -17
  49. package/src/audit/languageAnalysisEngine/report/models/reportListModel.ts +4 -1
  50. package/src/audit/languageAnalysisEngine/report/models/severityCountModel.ts +4 -0
  51. package/src/audit/languageAnalysisEngine/report/reportingFeature.ts +49 -17
  52. package/src/audit/languageAnalysisEngine/report/utils/reportUtils.ts +1 -1
  53. package/src/audit/save.js +32 -0
  54. package/src/commands/audit/auditController.ts +22 -13
  55. package/src/commands/audit/help.ts +24 -1
  56. package/src/commands/audit/processAudit.ts +6 -3
  57. package/src/commands/audit/saveFile.ts +5 -1
  58. package/src/commands/scan/sca/scaAnalysis.js +53 -22
  59. package/src/common/HTTPClient.js +7 -0
  60. package/src/common/versionChecker.ts +23 -4
  61. package/src/constants/constants.js +1 -1
  62. package/src/constants/locales.js +12 -11
  63. package/src/constants.js +9 -4
  64. package/src/index.ts +5 -3
  65. package/src/sbom/generateSbom.ts +1 -1
  66. package/src/scaAnalysis/common/formatMessage.js +27 -5
  67. package/src/scaAnalysis/common/treeUpload.js +0 -1
  68. package/src/scaAnalysis/go/goReadDepFile.js +1 -3
  69. package/src/scaAnalysis/java/analysis.js +5 -5
  70. package/src/scaAnalysis/javascript/analysis.js +127 -0
  71. package/src/scaAnalysis/javascript/index.js +56 -0
  72. package/src/scaAnalysis/php/analysis.js +98 -0
  73. package/src/scaAnalysis/php/index.js +11 -0
  74. package/src/scaAnalysis/python/analysis.js +8 -7
  75. package/src/scaAnalysis/ruby/analysis.js +8 -8
  76. package/src/scaAnalysis/ruby/index.js +2 -2
  77. package/src/scan/autoDetection.js +4 -4
  78. package/src/scan/fileUtils.js +13 -2
  79. package/src/utils/filterProjectPath.js +6 -2
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  const multiReplace = require('string-multiple-replace');
3
3
  const fs = require('fs');
4
- const readAndParseProjectFile = projectPath => {
5
- const filePath = filePathForWindows(projectPath + '/Pipfile');
4
+ const readAndParseProjectFile = file => {
5
+ const filePath = filePathForWindows(file + '/Pipfile');
6
6
  const pipFile = fs.readFileSync(filePath, 'utf8');
7
7
  const matcherObj = { '"': '' };
8
8
  const sequencer = ['"'];
@@ -10,18 +10,19 @@ const readAndParseProjectFile = projectPath => {
10
10
  const pythonArray = parsedPipfile.split('\n');
11
11
  return pythonArray.filter(element => element !== '' && !element.includes('#'));
12
12
  };
13
- const readAndParseLockFile = projectPath => {
14
- const filePath = filePathForWindows(projectPath + '/Pipfile.lock');
13
+ const readAndParseLockFile = file => {
14
+ const filePath = filePathForWindows(file + '/Pipfile.lock');
15
15
  const lockFile = fs.readFileSync(filePath, 'utf8');
16
16
  let parsedPipLock = JSON.parse(lockFile);
17
17
  parsedPipLock['defaults'] = parsedPipLock['default'];
18
+ delete parsedPipLock['default'];
18
19
  return parsedPipLock;
19
20
  };
20
21
  const getPythonDeps = config => {
21
22
  try {
22
- const parseProject = readAndParseProjectFile(config.projectPath);
23
- const parsePip = readAndParseLockFile(config.projectPath);
24
- return { pipfileLock: parseProject, pipfilDependanceies: parsePip };
23
+ const parseProject = readAndParseProjectFile(config.file);
24
+ const parsePip = readAndParseLockFile(config.file);
25
+ return { pipfileLock: parsePip, pipfilDependanceies: parseProject };
25
26
  }
26
27
  catch (err) {
27
28
  console.log(err.message.toString());
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  const fs = require('fs');
3
- const readAndParseGemfile = projectPath => {
4
- const fileName = filePathForWindows(projectPath + '/Gemfile');
3
+ const readAndParseGemfile = file => {
4
+ const fileName = filePathForWindows(file + '/Gemfile');
5
5
  const gemFile = fs.readFileSync(fileName, 'utf8');
6
6
  const rubyArray = gemFile.split('\n');
7
7
  let filteredRubyDep = rubyArray.filter(element => {
@@ -14,8 +14,8 @@ const readAndParseGemfile = projectPath => {
14
14
  }
15
15
  return filteredRubyDep;
16
16
  };
17
- const readAndParseGemLockFile = projectPath => {
18
- const fileName = filePathForWindows(projectPath + '/Gemfile.lock');
17
+ const readAndParseGemLockFile = file => {
18
+ const fileName = filePathForWindows(file + '/Gemfile.lock');
19
19
  const lockFile = fs.readFileSync(fileName, 'utf8');
20
20
  const dependencyRegEx = /^\s*([A-Za-z0-9.!@#$%\-^&*_+]*)\s*(\((.*?)\))/;
21
21
  const lines = lockFile.split('\n');
@@ -26,7 +26,7 @@ const readAndParseGemLockFile = projectPath => {
26
26
  };
27
27
  };
28
28
  const nonDependencyKeys = (line, sourceObject) => {
29
- const GEMFILE_KEY_VALUE = /^\s*([^:(]*)\s*\s*(.*)/;
29
+ const GEMFILE_KEY_VALUE = /^\s*([^:(]*)\s*\:*\s*(.*)/;
30
30
  let parts = GEMFILE_KEY_VALUE.exec(line);
31
31
  let key = parts[1].trim();
32
32
  let value = parts[2] || '';
@@ -164,7 +164,7 @@ const getSourceArray = (lines, dependencyRegEx) => {
164
164
  }
165
165
  if ((currentWS === 4 && nexlineWS === 4) ||
166
166
  (currentWS === 6 && nexlineWS === 4) ||
167
- nexlineWS === '') {
167
+ nexlineWS == '') {
168
168
  let newObj = {};
169
169
  newObj = JSON.parse(JSON.stringify(sourceObject));
170
170
  sources.push(newObj);
@@ -192,8 +192,8 @@ const buildSourceDependencyWithVersion = (whitespaceRegx, dependencyRegEx, line,
192
192
  };
193
193
  const getRubyDeps = config => {
194
194
  try {
195
- const parsedGem = readAndParseGemfile(config.projectPath);
196
- const parsedLock = readAndParseGemLockFile(config.projectPath);
195
+ const parsedGem = readAndParseGemfile(config.file);
196
+ const parsedLock = readAndParseGemLockFile(config.file);
197
197
  return { gemfilesDependanceies: parsedGem, gemfileLock: parsedLock };
198
198
  }
199
199
  catch (err) {
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
- const { getRubyDeps } = require('./analysis');
2
+ const analysis = require('./analysis');
3
3
  const { createRubyTSMessage } = require('../common/formatMessage');
4
4
  const rubyAnalysis = (config, languageFiles) => {
5
- const rubyDeps = getRubyDeps(config, languageFiles.RUBY);
5
+ const rubyDeps = analysis.getRubyDeps(config, languageFiles.RUBY);
6
6
  return createRubyTSMessage(rubyDeps);
7
7
  };
8
8
  module.exports = {
@@ -37,14 +37,14 @@ const autoDetectAuditFilesAndLanguages = async () => {
37
37
  return languagesFound;
38
38
  }
39
39
  else {
40
- console.log('found multiple languages, please specify one using --file to run SCA analysis');
40
+ console.log('found multiple languages, please specify one using --file to run SCA audit');
41
41
  }
42
42
  };
43
- const manualDetectAuditFilesAndLanguages = projectPath => {
44
- let projectRootFilenames = rootFile.getProjectRootFilenames(projectPath);
43
+ const manualDetectAuditFilesAndLanguages = file => {
44
+ let projectRootFilenames = rootFile.getProjectRootFilenames(file);
45
45
  let identifiedLanguages = languageResolver.deduceLanguageScaAnalysis(projectRootFilenames);
46
46
  if (Object.keys(identifiedLanguages).length === 0) {
47
- console.log(i18n.__('languageAnalysisNoLanguage', projectPath));
47
+ console.log(i18n.__('languageAnalysisNoLanguage', file));
48
48
  return [];
49
49
  }
50
50
  return [identifiedLanguages];
@@ -22,7 +22,7 @@ const findFilesJava = async (languagesFound) => {
22
22
  return languagesFound;
23
23
  };
24
24
  const findFilesJavascript = async (languagesFound) => {
25
- const result = await fg(['**/package.json', '**/yarn.lock', '**/package.lock.json'], {
25
+ const result = await fg(['**/package.json', '**/yarn.lock', '**/package-lock.json'], {
26
26
  dot: false,
27
27
  deep: 1,
28
28
  onlyFiles: true
@@ -92,7 +92,18 @@ const fileExists = path => {
92
92
  };
93
93
  const fileIsEmpty = path => {
94
94
  if (fileExists(path) && checkFilePermissions(path)) {
95
- return fs.readFileSync(path).length === 0;
95
+ try {
96
+ return fs.readFileSync(path).length === 0;
97
+ }
98
+ catch (e) {
99
+ if (e.message.toString().includes('illegal operation on a directory, read')) {
100
+ console.log('file provided cannot be a directory');
101
+ }
102
+ else {
103
+ console.log(e.message.toString());
104
+ }
105
+ process.exit(0);
106
+ }
96
107
  }
97
108
  return false;
98
109
  };
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  const path = require('path');
3
+ const child_process = require('child_process');
3
4
  function resolveFilePath(filepath) {
4
5
  if (filepath[0] === '~') {
5
6
  return path.join(process.env.HOME, filepath.slice(1));
@@ -7,11 +8,15 @@ function resolveFilePath(filepath) {
7
8
  return filepath;
8
9
  }
9
10
  const returnProjectPath = () => {
10
- if (process.env.PWD !== (undefined || null || 'undefined')) {
11
+ if (process.platform == 'win32') {
12
+ let winPath = child_process.execSync('cd').toString();
13
+ return winPath.replace(/\//g, '\\').trim();
14
+ }
15
+ else if (process.env.PWD !== (undefined || null || 'undefined')) {
11
16
  return process.env.PWD;
12
17
  }
13
18
  else {
14
- return process.argv[process.argv.indexOf('--project_path') + 1];
19
+ return process.argv[process.argv.indexOf('--file') + 1];
15
20
  }
16
21
  };
17
22
  module.exports = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contrast/contrast",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
4
4
  "description": "Contrast Security's command line tool",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -23,7 +23,8 @@
23
23
  "test": "jest --testPathIgnorePatterns=./test-integration/",
24
24
  "test-int": "jest ./test-integration/",
25
25
  "test-int-scan": "jest ./test-integration/scan",
26
- "test-int-audit": "jest ./test-integration/audit",
26
+ "test-int-audit": "jest ./test-integration/audit/audit.spec.js",
27
+ "test-int-audit-experimental": "jest ./test-integration/audit/audit-experimental.spec.js",
27
28
  "format": "prettier --write \"**/*.{ts,tsx,js,json,md,yml}\" .eslintrc.*",
28
29
  "check-format": "prettier --check \"**/*.{ts,tsx,js,json,md,yml}\" .eslintrc.*",
29
30
  "coverage-local": "nyc --reporter=text mocha './test/**/*.spec.js'",
@@ -53,7 +54,6 @@
53
54
  "fast-glob": "^3.2.11",
54
55
  "i18n": "^0.14.2",
55
56
  "js-yaml": "^4.1.0",
56
- "latest-version": "5.1.0",
57
57
  "lodash": "^4.17.21",
58
58
  "log-symbols": "^4.1.0",
59
59
  "open": "^8.4.0",
@@ -8,8 +8,8 @@ import {
8
8
  import { getProjectRootFilenames } from '../languageAnalysisEngine/getProjectRootFilenames'
9
9
 
10
10
  export function identifyLanguages(config: any) {
11
- const { projectPath } = config
12
- const projectRootFilenames = getProjectRootFilenames(projectPath)
11
+ const { file } = config
12
+ const projectRootFilenames = getProjectRootFilenames(file)
13
13
 
14
14
  const identifiedLanguages = projectRootFilenames.reduce(
15
15
  (accumulator: any, filename: string) => {
@@ -20,7 +20,7 @@ export function identifyLanguages(config: any) {
20
20
  )
21
21
 
22
22
  if (Object.keys(identifiedLanguages).length === 0) {
23
- throw new Error(i18n.__('languageAnalysisNoLanguage', projectPath))
23
+ throw new Error(i18n.__('languageAnalysisNoLanguage', file))
24
24
  }
25
25
 
26
26
  return reduceIdentifiedLanguages(identifiedLanguages)
@@ -1,10 +1,5 @@
1
- const i18n = require('i18n')
2
1
  const { getHttpClient, handleResponseErrors } = require('../../utils/commonApi')
3
2
 
4
- const displaySuccessMessage = () => {
5
- console.log(i18n.__('catalogueSuccessCommand'))
6
- }
7
-
8
3
  const catalogueApplication = async config => {
9
4
  const client = getHttpClient(config)
10
5
  let appId
@@ -14,6 +9,8 @@ const catalogueApplication = async config => {
14
9
  if (res.statusCode === 201) {
15
10
  //displaySuccessMessage(config, res.body.application.app_id)
16
11
  appId = res.body.application.app_id
12
+ } else if (doesMessagesContainAppId(res)) {
13
+ appId = tryRetrieveAppIdFromMessages(res.body.messages)
17
14
  } else {
18
15
  handleResponseErrors(res, 'catalogue')
19
16
  }
@@ -24,6 +21,31 @@ const catalogueApplication = async config => {
24
21
  return appId
25
22
  }
26
23
 
24
+ const doesMessagesContainAppId = res => {
25
+ const regex = /(Application ID =)/
26
+ if (
27
+ res.statusCode === 400 &&
28
+ res.body.messages.filter(message => regex.exec(message))[0]
29
+ ) {
30
+ return true
31
+ }
32
+
33
+ return false
34
+ }
35
+
36
+ const tryRetrieveAppIdFromMessages = messages => {
37
+ let appId
38
+ messages.forEach(message => {
39
+ if (message.includes('Application ID')) {
40
+ appId = message.split('=')[1].replace(/\s+/g, '')
41
+ }
42
+ })
43
+
44
+ return appId
45
+ }
46
+
27
47
  module.exports = {
28
- catalogueApplication: catalogueApplication
48
+ catalogueApplication: catalogueApplication,
49
+ doesMessagesContainAppId,
50
+ tryRetrieveAppIdFromMessages
29
51
  }
@@ -5,15 +5,15 @@ const path = require('path')
5
5
  * language, project file name and paths
6
6
  */
7
7
  module.exports = exports = (analysis, next) => {
8
- const { projectPath, languageAnalysis } = analysis
8
+ const { file, languageAnalysis } = analysis
9
9
  languageAnalysis.identifiedLanguageInfo = getIdentifiedLanguageInfo(
10
- projectPath,
10
+ file,
11
11
  languageAnalysis.identifiedLanguages
12
12
  )
13
13
  next()
14
14
  }
15
15
 
16
- const getIdentifiedLanguageInfo = (projectPath, identifiedLanguages) => {
16
+ const getIdentifiedLanguageInfo = (file, identifiedLanguages) => {
17
17
  const [language] = Object.keys(identifiedLanguages)
18
18
  const {
19
19
  projectFilenames: [projectFilename],
@@ -23,14 +23,14 @@ const getIdentifiedLanguageInfo = (projectPath, identifiedLanguages) => {
23
23
  let identifiedLanguageInfo = {
24
24
  language,
25
25
  projectFilename,
26
- projectFilePath: path.join(projectPath, projectFilename)
26
+ projectFilePath: path.join(file, projectFilename)
27
27
  }
28
28
 
29
29
  if (lockFilename) {
30
30
  identifiedLanguageInfo = {
31
31
  ...identifiedLanguageInfo,
32
32
  lockFilename,
33
- lockFilePath: path.join(projectPath, lockFilename)
33
+ lockFilePath: path.join(file, lockFilename)
34
34
  }
35
35
  }
36
36
 
@@ -9,21 +9,21 @@ const i18n = require('i18n')
9
9
  * Will fail and throw for a manner of reasons when doing file/directory
10
10
  * inspection.
11
11
  *
12
- * @param {string} projectPath - The path to a projects root directory or a
12
+ * @param {string} file - The path to a projects root directory or a
13
13
  * specific project file
14
14
  *
15
15
  * @return {string[]} List of filenames associated with a projects root
16
16
  * directory or the name of the specific project file if that was provided to
17
- * the 'projectPath' parameter
17
+ * the 'file' parameter
18
18
  *
19
19
  * @throws {Error} If the project path doesn't exist
20
20
  * @throws {Error} If the project path information can't be collected
21
21
  * @throws {Error} If a non-file or non-directory inspected
22
22
  */
23
23
  module.exports = exports = (analysis, next) => {
24
- const { projectPath, languageAnalysis } = analysis
24
+ const { file, languageAnalysis } = analysis
25
25
  try {
26
- languageAnalysis.projectRootFilenames = getProjectRootFilenames(projectPath)
26
+ languageAnalysis.projectRootFilenames = getProjectRootFilenames(file)
27
27
  } catch (err) {
28
28
  next(err)
29
29
  return
@@ -31,13 +31,13 @@ module.exports = exports = (analysis, next) => {
31
31
  next()
32
32
  }
33
33
 
34
- const getProjectRootFilenames = projectPath => {
34
+ const getProjectRootFilenames = file => {
35
35
  let projectStats = null
36
36
  try {
37
- projectStats = fs.statSync(projectPath)
37
+ projectStats = fs.statSync(file)
38
38
  } catch (err) {
39
39
  throw new Error(
40
- i18n.__('languageAnalysisProjectRootFileNameFailure', projectPath) +
40
+ i18n.__('languageAnalysisProjectRootFileNameFailure', file) +
41
41
  `${err.message}`
42
42
  )
43
43
  }
@@ -45,10 +45,10 @@ const getProjectRootFilenames = projectPath => {
45
45
  // Return the contents of a directory...
46
46
  if (projectStats.isDirectory()) {
47
47
  try {
48
- return fs.readdirSync(projectPath)
48
+ return fs.readdirSync(file)
49
49
  } catch (err) {
50
50
  throw new Error(
51
- i18n.__('languageAnalysisProjectRootFileNameReadError', projectPath) +
51
+ i18n.__('languageAnalysisProjectRootFileNameReadError', file) +
52
52
  `${err.message}`
53
53
  )
54
54
  }
@@ -57,14 +57,14 @@ const getProjectRootFilenames = projectPath => {
57
57
  // If we are working with a file return it in a list as we do when we work
58
58
  // with a directory...
59
59
  if (projectStats.isFile()) {
60
- return [path.basename(projectPath)]
60
+ return [path.basename(file)]
61
61
  }
62
62
 
63
63
  // Error out if we are working with something like a socket file or some
64
64
  // other craziness...
65
65
  throw new Error(
66
66
  i18n.__('languageAnalysisProjectRootFileNameMissingError'),
67
- projectPath
67
+ file
68
68
  )
69
69
  }
70
70
 
@@ -10,10 +10,10 @@ const checkIdentifiedLanguageHasLockFile = require('./checkIdentifiedLanguageHas
10
10
  const getIdentifiedLanguageInfo = require('./getIdentifiedLanguageInfo')
11
11
  const { libraryAnalysisError } = require('../../common/errorHandling')
12
12
 
13
- module.exports = exports = (projectPath, callback, appId, config) => {
13
+ module.exports = exports = (file, callback, appId, config) => {
14
14
  // Create an analysis engine to identify the project language
15
15
  const ae = new AnalysisEngine({
16
- projectPath,
16
+ file,
17
17
  appId,
18
18
  languageAnalysis: { appId: appId },
19
19
  config
@@ -11,17 +11,13 @@ const phpAE = require('../phpAnalysisEngine')
11
11
  const goAE = require('../goAnalysisEngine')
12
12
  const { vulnerabilityReport } = require('./report/reportingFeature')
13
13
  const { newSendSnapShot } = require('../languageAnalysisEngine/sendSnapshot')
14
- const fs = require('fs')
15
- const chalk = require('chalk')
16
- const saveFile = require('../../commands/audit/saveFile').default
17
- const generateSbom = require('../../sbom/generateSbom').default
18
14
  const {
19
- failSpinner,
20
15
  returnOra,
21
16
  startSpinner,
22
17
  succeedSpinner
23
18
  } = require('../../utils/oraWrapper')
24
19
  const { pollForSnapshotCompletition } = require('./sendSnapshot')
20
+ const auditSave = require('../save')
25
21
 
26
22
  module.exports = exports = (err, analysis) => {
27
23
  const { identifiedLanguageInfo } = analysis.languageAnalysis
@@ -57,17 +53,17 @@ module.exports = exports = (err, analysis) => {
57
53
  const snapshotResponse = await newSendSnapShot(analysis, catalogueAppId)
58
54
 
59
55
  //poll for completion
60
- const pollResult = await pollForSnapshotCompletition(
56
+ await pollForSnapshotCompletition(
61
57
  analysis.config,
62
58
  snapshotResponse.id,
63
59
  reportSpinner
64
60
  )
65
- succeedSpinner(reportSpinner, 'Contrast SCA analysis complete')
61
+ succeedSpinner(reportSpinner, i18n.__('auditSCAAnalysisComplete'))
66
62
 
67
63
  await vulnerabilityReport(analysis, catalogueAppId, snapshotResponse.id)
68
64
 
69
65
  //should be moved to processAudit.ts once promises implemented
70
- await auditSave(config)
66
+ await auditSave.auditSave(config)
71
67
  }
72
68
 
73
69
  if (identifiedLanguageInfo.language === DOTNET) {
@@ -98,27 +94,3 @@ module.exports = exports = (err, analysis) => {
98
94
  goAE(identifiedLanguageInfo, analysis.config, langCallback)
99
95
  }
100
96
  }
101
-
102
- async function auditSave(config) {
103
- //should be moved to processAudit.ts once promises implemented
104
- if (config.save) {
105
- if (config.save.toLowerCase() === 'sbom') {
106
- saveFile(config, await generateSbom(config))
107
-
108
- const filename = `${config.applicationId}-sbom-cyclonedx.json`
109
- if (fs.existsSync(filename)) {
110
- console.log(i18n.__('auditSBOMSaveSuccess') + ` - ${filename}`)
111
- } else {
112
- console.log(
113
- chalk.yellow.bold(
114
- `\n Unable to save ${filename} Software Bill of Materials (SBOM)`
115
- )
116
- )
117
- }
118
- } else {
119
- console.log(i18n.__('auditBadFiletypeSpecifiedForSave'))
120
- }
121
- } else if (config.save === null) {
122
- console.log(i18n.__('auditNoFiletypeSpecifiedForSave'))
123
- }
124
- }
@@ -46,37 +46,38 @@ const deduceLanguageScaAnalysis = filenames => {
46
46
 
47
47
  if (isNodeProjectFilename(filename)) {
48
48
  deducedLanguages.push(filename)
49
- language = NODE
49
+ language = JAVASCRIPT
50
50
  }
51
- //
51
+
52
52
  // if (isDotNetProjectFilename(filename)) {
53
53
  // deducedLanguages.push({language: DOTNET, projectFilename: filename})
54
54
  // }
55
- //
55
+
56
56
  if (isRubyProjectFilename(filename)) {
57
57
  deducedLanguages.push(filename)
58
58
  language = RUBY
59
59
  }
60
- //
60
+
61
61
  if (isPythonProjectFilename(filename)) {
62
62
  deducedLanguages.push(filename)
63
63
  language = PYTHON
64
64
  }
65
- //
66
- // if (isPhpProjectFilename(filename)) {
67
- // deducedLanguages.push({language: PHP, projectFilename: filename})
68
- // }
69
- //
65
+
66
+ if (isPhpProjectFilename(filename)) {
67
+ deducedLanguages.push({ language: PHP, projectFilename: filename })
68
+ language = PHP
69
+ }
70
+
70
71
  // // Check for lock filenames...
71
72
  // if (isDotNetLockFilename(filename)) {
72
73
  // deducedLanguages.push({language: DOTNET, lockFilename: filename})
73
74
  // }
74
- //
75
+
75
76
  if (isNodeLockFilename(filename)) {
76
77
  deducedLanguages.push(filename)
77
- language = NODE
78
+ language = JAVASCRIPT
78
79
  }
79
- //
80
+
80
81
  // if (isRubyLockFilename(filename)) {
81
82
  // deducedLanguages.push({language: RUBY, lockFilename: filename})
82
83
  // }
@@ -85,11 +86,11 @@ const deduceLanguageScaAnalysis = filenames => {
85
86
  // if (isPipfileLockLockFilename(filename)) {
86
87
  // deducedLanguages.push({language: PYTHON, lockFilename: filename})
87
88
  // }
88
- //
89
- // if (isPhpLockFilename(filename)) {
90
- // deducedLanguages.push({language: PHP, lockFilename: filename})
91
- // }
92
- //
89
+
90
+ if (isPhpLockFilename(filename)) {
91
+ deducedLanguages.push({ language: PHP, lockFilename: filename })
92
+ }
93
+
93
94
  // go does not have a lockfile, it should have a go.mod file containing the modules
94
95
  if (isGoProjectFilename(filename)) {
95
96
  deducedLanguages.push({ language: GO, projectFilename: filename })
@@ -192,7 +193,7 @@ const reduceIdentifiedLanguages = identifiedLanguages =>
192
193
  * specifies a specific language
193
194
  */
194
195
  module.exports = exports = (analysis, next) => {
195
- const { projectPath, languageAnalysis, config } = analysis
196
+ const { file, languageAnalysis, config } = analysis
196
197
 
197
198
  let identifiedLanguages = languageAnalysis.projectRootFilenames.reduce(
198
199
  (accumulator, filename) => {
@@ -203,7 +204,7 @@ module.exports = exports = (analysis, next) => {
203
204
  )
204
205
 
205
206
  if (Object.keys(identifiedLanguages).length === 0) {
206
- next(new Error(i18n.__('languageAnalysisNoLanguage', projectPath)))
207
+ next(new Error(i18n.__('languageAnalysisNoLanguage', file)))
207
208
  return
208
209
  }
209
210