@contrast/contrast 1.0.10 → 1.0.11

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 (78) hide show
  1. package/README.md +1 -1
  2. package/dist/audit/languageAnalysisEngine/report/commonReportingFunctions.js +39 -28
  3. package/dist/audit/languageAnalysisEngine/report/models/reportGuidanceModel.js +6 -0
  4. package/dist/audit/languageAnalysisEngine/report/models/reportOutputModel.js +1 -2
  5. package/dist/audit/languageAnalysisEngine/report/models/severityCountModel.js +1 -0
  6. package/dist/audit/languageAnalysisEngine/report/reportingFeature.js +11 -7
  7. package/dist/audit/languageAnalysisEngine/report/utils/reportUtils.js +1 -2
  8. package/dist/commands/audit/auditConfig.js +3 -3
  9. package/dist/commands/audit/processAudit.js +4 -2
  10. package/dist/commands/auth/auth.js +1 -1
  11. package/dist/commands/config/config.js +2 -2
  12. package/dist/commands/scan/processScan.js +11 -4
  13. package/dist/commands/scan/sca/scaAnalysis.js +10 -3
  14. package/dist/common/HTTPClient.js +9 -0
  15. package/dist/common/fail.js +66 -0
  16. package/dist/common/versionChecker.js +1 -1
  17. package/dist/constants/constants.js +1 -1
  18. package/dist/constants/locales.js +6 -3
  19. package/dist/constants.js +39 -1
  20. package/dist/index.js +5 -2
  21. package/dist/scaAnalysis/common/scaParserForGoAndJava.js +32 -0
  22. package/dist/scaAnalysis/common/treeUpload.js +20 -5
  23. package/dist/scaAnalysis/dotnet/analysis.js +15 -3
  24. package/dist/scaAnalysis/go/goAnalysis.js +8 -2
  25. package/dist/scaAnalysis/java/analysis.js +10 -6
  26. package/dist/scaAnalysis/java/index.js +7 -1
  27. package/dist/scaAnalysis/java/javaBuildDepsParser.js +19 -3
  28. package/dist/scaAnalysis/python/analysis.js +43 -5
  29. package/dist/scaAnalysis/python/index.js +7 -2
  30. package/dist/scaAnalysis/ruby/analysis.js +14 -4
  31. package/dist/scan/formatScanOutput.js +6 -5
  32. package/dist/scan/populateProjectIdAndProjectName.js +5 -0
  33. package/dist/scan/scan.js +4 -0
  34. package/dist/scan/scanConfig.js +3 -3
  35. package/dist/scan/scanResults.js +39 -3
  36. package/dist/telemetry/telemetry.js +137 -0
  37. package/dist/utils/getConfig.js +2 -2
  38. package/dist/utils/parsedCLIOptions.js +3 -1
  39. package/dist/utils/requestUtils.js +7 -1
  40. package/package.json +1 -1
  41. package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.ts +57 -39
  42. package/src/audit/languageAnalysisEngine/report/models/reportGuidanceModel.ts +5 -0
  43. package/src/audit/languageAnalysisEngine/report/models/reportOutputModel.ts +1 -7
  44. package/src/audit/languageAnalysisEngine/report/models/severityCountModel.ts +2 -0
  45. package/src/audit/languageAnalysisEngine/report/reportingFeature.ts +15 -8
  46. package/src/audit/languageAnalysisEngine/report/utils/reportUtils.ts +2 -2
  47. package/src/commands/audit/auditConfig.ts +10 -3
  48. package/src/commands/audit/processAudit.ts +16 -2
  49. package/src/commands/auth/auth.js +3 -1
  50. package/src/commands/config/config.js +4 -2
  51. package/src/commands/scan/processScan.js +18 -4
  52. package/src/commands/scan/sca/scaAnalysis.js +11 -3
  53. package/src/common/HTTPClient.js +14 -0
  54. package/src/common/fail.js +75 -0
  55. package/src/common/versionChecker.ts +1 -1
  56. package/src/constants/constants.js +1 -1
  57. package/src/constants/locales.js +8 -4
  58. package/src/constants.js +43 -1
  59. package/src/index.ts +17 -2
  60. package/src/scaAnalysis/common/scaParserForGoAndJava.js +41 -0
  61. package/src/scaAnalysis/common/treeUpload.js +21 -6
  62. package/src/scaAnalysis/dotnet/analysis.js +21 -3
  63. package/src/scaAnalysis/go/goAnalysis.js +9 -2
  64. package/src/scaAnalysis/java/analysis.js +11 -6
  65. package/src/scaAnalysis/java/index.js +9 -1
  66. package/src/scaAnalysis/java/javaBuildDepsParser.js +25 -6
  67. package/src/scaAnalysis/python/analysis.js +49 -5
  68. package/src/scaAnalysis/python/index.js +7 -2
  69. package/src/scaAnalysis/ruby/analysis.js +16 -4
  70. package/src/scan/formatScanOutput.ts +7 -5
  71. package/src/scan/populateProjectIdAndProjectName.js +5 -1
  72. package/src/scan/scan.ts +4 -0
  73. package/src/scan/scanConfig.js +5 -3
  74. package/src/scan/scanResults.js +46 -3
  75. package/src/telemetry/telemetry.ts +154 -0
  76. package/src/utils/getConfig.ts +4 -6
  77. package/src/utils/parsedCLIOptions.js +14 -1
  78. package/src/utils/requestUtils.js +8 -1
package/src/constants.js CHANGED
@@ -1,6 +1,7 @@
1
1
  const commandLineUsage = require('command-line-usage')
2
2
  const i18n = require('i18n')
3
3
  const { en_locales } = require('./constants/locales.js')
4
+ const { parseSeverity } = require('./common/fail')
4
5
 
5
6
  i18n.configure({
6
7
  staticCatalog: {
@@ -106,6 +107,24 @@ const scanOptionDefinitions = [
106
107
  '}: ' +
107
108
  i18n.__('constantsProxyServer')
108
109
  },
110
+ {
111
+ name: 'fail',
112
+ type: Boolean,
113
+ description:
114
+ '{bold ' +
115
+ i18n.__('constantsOptional') +
116
+ '}: ' +
117
+ i18n.__('failOptionErrorMessage')
118
+ },
119
+ {
120
+ name: 'severity',
121
+ type: severity => parseSeverity(severity),
122
+ description:
123
+ '{bold ' +
124
+ i18n.__('constantsOptional') +
125
+ '}: ' +
126
+ i18n.__('constantsSeverity')
127
+ },
109
128
  {
110
129
  name: 'ff',
111
130
  type: Boolean,
@@ -220,6 +239,24 @@ const auditOptionDefinitions = [
220
239
  '}: ' +
221
240
  i18n.__('constantsFilePath')
222
241
  },
242
+ {
243
+ name: 'fail',
244
+ type: Boolean,
245
+ description:
246
+ '{bold ' +
247
+ i18n.__('constantsOptional') +
248
+ '}: ' +
249
+ i18n.__('failOptionErrorMessage')
250
+ },
251
+ {
252
+ name: 'severity',
253
+ type: severity => parseSeverity(severity),
254
+ description:
255
+ '{bold ' +
256
+ i18n.__('constantsOptional') +
257
+ '}: ' +
258
+ i18n.__('constantsSeverity')
259
+ },
223
260
  {
224
261
  name: 'app-groups',
225
262
  description:
@@ -257,6 +294,7 @@ const auditOptionDefinitions = [
257
294
  {
258
295
  name: 'ignore-dev',
259
296
  type: Boolean,
297
+ alias: 'i',
260
298
  description:
261
299
  '{bold ' +
262
300
  i18n.__('constantsOptional') +
@@ -293,7 +331,6 @@ const auditOptionDefinitions = [
293
331
  },
294
332
  {
295
333
  name: 'host',
296
- alias: 'h',
297
334
  description:
298
335
  '{bold ' +
299
336
  i18n.__('constantsRequired') +
@@ -341,6 +378,11 @@ const auditOptionDefinitions = [
341
378
  i18n.__('constantsOptional') +
342
379
  '}: ' +
343
380
  i18n.__('scanOptionsTimeoutSummary')
381
+ },
382
+ {
383
+ name: 'help',
384
+ alias: 'h',
385
+ type: Boolean
344
386
  }
345
387
  ]
346
388
 
package/src/index.ts CHANGED
@@ -14,6 +14,7 @@ import {
14
14
  isCorrectNodeVersion
15
15
  } from './common/versionChecker'
16
16
  import { findCommandOnError } from './common/errorHandling'
17
+ import { sendTelemetryConfigAsConfObj } from './telemetry/telemetry'
17
18
 
18
19
  const {
19
20
  commandLineDefinitions: { mainUsageGuide, mainDefinition }
@@ -75,11 +76,11 @@ const start = async () => {
75
76
  }
76
77
 
77
78
  if (command === 'scan') {
78
- return await processScan(argvMain)
79
+ return await processScan(config, argvMain)
79
80
  }
80
81
 
81
82
  if (command === 'audit') {
82
- return await processAudit(argvMain)
83
+ return await processAudit(config, argvMain)
83
84
  }
84
85
 
85
86
  if (
@@ -98,10 +99,24 @@ const start = async () => {
98
99
  : console.log(
99
100
  `Unknown Command: ${command} \nUse --help for the full list`
100
101
  )
102
+ await sendTelemetryConfigAsConfObj(
103
+ config,
104
+ command,
105
+ argvMain,
106
+ 'FAILURE',
107
+ 'undefined'
108
+ )
101
109
  } else {
102
110
  console.log(
103
111
  `Unknown Command: ${command} \nUse --help for the full list`
104
112
  )
113
+ await sendTelemetryConfigAsConfObj(
114
+ config,
115
+ command,
116
+ argvMain,
117
+ 'FAILURE',
118
+ 'undefined'
119
+ )
105
120
  }
106
121
  process.exit(9)
107
122
  } else {
@@ -0,0 +1,41 @@
1
+ const parseDependenciesForSCAServices = dependencyTreeObject => {
2
+ let parsedDependencyTree = {}
3
+ let subDeps
4
+
5
+ for (let tree in dependencyTreeObject) {
6
+ let unParsedDependencyTree = dependencyTreeObject[tree]
7
+ for (let dependency in unParsedDependencyTree) {
8
+ subDeps = parseSubDependencies(unParsedDependencyTree[dependency].edges)
9
+
10
+ let parsedDependency = {
11
+ name: unParsedDependencyTree[dependency].artifactID,
12
+ group: unParsedDependencyTree[dependency].group,
13
+ version: unParsedDependencyTree[dependency].version,
14
+ directDependency: unParsedDependencyTree[dependency].type === 'direct',
15
+ isProduction: true,
16
+ dependencies: subDeps
17
+ }
18
+ parsedDependencyTree[dependency] = parsedDependency
19
+ }
20
+ }
21
+ return parsedDependencyTree
22
+ }
23
+
24
+ const parseSubDependencies = dependencies => {
25
+ // converting:
26
+ // dependencies: {
27
+ // 'gopkg.in/check.v1@v0.0.0-2': 'gopkg.in/check.v1@v0.0.0-2'
28
+ // }
29
+ // to:
30
+ // dependencies: [ 'gopkg.in/check.v1@v0.0.0-2' ]
31
+ let subDeps = []
32
+ for (let x in dependencies) {
33
+ subDeps.push(dependencies[x])
34
+ }
35
+ return subDeps
36
+ }
37
+
38
+ module.exports = {
39
+ parseDependenciesForSCAServices,
40
+ parseSubDependencies
41
+ }
@@ -2,12 +2,14 @@ const commonApi = require('../../utils/commonApi')
2
2
  const { APP_VERSION } = require('../../constants/constants')
3
3
 
4
4
  const commonSendSnapShot = async (analysis, config) => {
5
- const requestBody = {
6
- appID: config.applicationId,
7
- cliVersion: APP_VERSION,
8
- snapshot: analysis
9
- }
10
-
5
+ let requestBody = {}
6
+ config.experimental === true
7
+ ? (requestBody = sendToSCAServices(config, analysis))
8
+ : (requestBody = {
9
+ appID: config.applicationId,
10
+ cliVersion: APP_VERSION,
11
+ snapshot: analysis
12
+ })
11
13
  const client = commonApi.getHttpClient(config)
12
14
  return client
13
15
  .sendSnapshot(requestBody, config)
@@ -23,6 +25,19 @@ const commonSendSnapShot = async (analysis, config) => {
23
25
  })
24
26
  }
25
27
 
28
+ const sendToSCAServices = (config, analysis) => {
29
+ return {
30
+ applicationId: config.applicationId,
31
+ dependencyTree: analysis,
32
+ organizationId: config.organizationId,
33
+ language: config.language,
34
+ tool: {
35
+ name: 'Contrast Codesec',
36
+ version: APP_VERSION
37
+ }
38
+ }
39
+ }
40
+
26
41
  module.exports = {
27
42
  commonSendSnapShot
28
43
  }
@@ -40,9 +40,26 @@ const readAndParseLockFile = lockFilePath => {
40
40
  return lockFile
41
41
  }
42
42
 
43
+ const checkForCorrectFiles = languageFiles => {
44
+ if (!languageFiles.includes('packages.lock.json')) {
45
+ throw new Error(i18n.__('languageAnalysisHasNoLockFile', '.NET'))
46
+ }
47
+
48
+ if (!languageFiles.some(i => i.includes('.csproj'))) {
49
+ throw new Error(i18n.__('languageAnalysisProjectFileError', '.NET'))
50
+ }
51
+ }
52
+
43
53
  const getDotNetDeps = (filePath, languageFiles) => {
44
- const projectFile = readAndParseProjectFile(filePath + `/${languageFiles[0]}`)
45
- const lockFile = readAndParseLockFile(filePath + `/${languageFiles[1]}`)
54
+ checkForCorrectFiles(languageFiles)
55
+ const projectFileName = languageFiles.find(fileName =>
56
+ fileName.includes('.csproj')
57
+ )
58
+ const lockFileName = languageFiles.find(fileName =>
59
+ fileName.includes('.json')
60
+ )
61
+ const projectFile = readAndParseProjectFile(filePath + `/${projectFileName}`)
62
+ const lockFile = readAndParseLockFile(filePath + `/${lockFileName}`)
46
63
 
47
64
  return { projectFile, lockFile }
48
65
  }
@@ -50,5 +67,6 @@ const getDotNetDeps = (filePath, languageFiles) => {
50
67
  module.exports = {
51
68
  getDotNetDeps,
52
69
  readAndParseProjectFile,
53
- readAndParseLockFile
70
+ readAndParseLockFile,
71
+ checkForCorrectFiles
54
72
  }
@@ -1,14 +1,21 @@
1
1
  const { createGoTSMessage } = require('../common/formatMessage')
2
+ const {
3
+ parseDependenciesForSCAServices
4
+ } = require('../common/scaParserForGoAndJava')
2
5
  const goReadDepFile = require('./goReadDepFile')
3
6
  const goParseDeps = require('./goParseDeps')
4
7
 
5
- const goAnalysis = (config, languageFiles) => {
8
+ const goAnalysis = config => {
6
9
  try {
7
10
  const rawGoDependencies = goReadDepFile.getGoDependencies(config)
8
11
  const parsedGoDependencies =
9
12
  goParseDeps.parseGoDependencies(rawGoDependencies)
10
13
 
11
- return createGoTSMessage(parsedGoDependencies)
14
+ if (config.experimental) {
15
+ return parseDependenciesForSCAServices(parsedGoDependencies)
16
+ } else {
17
+ return createGoTSMessage(parsedGoDependencies)
18
+ }
12
19
  } catch (e) {
13
20
  console.log(e.message.toString())
14
21
  }
@@ -6,9 +6,13 @@ const fs = require('fs')
6
6
  const MAVEN = 'maven'
7
7
  const GRADLE = 'gradle'
8
8
 
9
- const determineProjectTypeAndCwd = (files, file) => {
9
+ const determineProjectTypeAndCwd = (files, config) => {
10
10
  const projectData = {}
11
11
 
12
+ if (files.length > 1) {
13
+ files = files.filter(i => config.fileName.includes(i))
14
+ }
15
+
12
16
  if (files[0].includes('pom.xml')) {
13
17
  projectData.projectType = MAVEN
14
18
  } else if (files[0].includes('build.gradle')) {
@@ -16,9 +20,9 @@ const determineProjectTypeAndCwd = (files, file) => {
16
20
  }
17
21
 
18
22
  //clean up the path to be a folder not a file
19
- projectData.cwd = file
20
- ? file.replace('pom.xml', '').replace('build.gradle', '')
21
- : file
23
+ projectData.cwd = config.file
24
+ ? config.file.replace('pom.xml', '').replace('build.gradle', '')
25
+ : config.file
22
26
 
23
27
  return projectData
24
28
  }
@@ -124,7 +128,7 @@ const getJavaBuildDeps = (config, files) => {
124
128
  }
125
129
 
126
130
  try {
127
- const projectData = determineProjectTypeAndCwd(files, config.file)
131
+ const projectData = determineProjectTypeAndCwd(files, config)
128
132
  if (projectData.projectType === MAVEN) {
129
133
  output.mvnDependancyTreeOutput = buildMaven(config, projectData, timeout)
130
134
  } else if (projectData.projectType === GRADLE) {
@@ -138,5 +142,6 @@ const getJavaBuildDeps = (config, files) => {
138
142
  }
139
143
 
140
144
  module.exports = {
141
- getJavaBuildDeps
145
+ getJavaBuildDeps,
146
+ determineProjectTypeAndCwd
142
147
  }
@@ -1,6 +1,9 @@
1
1
  const analysis = require('./analysis')
2
2
  const { parseBuildDeps } = require('./javaBuildDepsParser')
3
3
  const { createJavaTSMessage } = require('../common/formatMessage')
4
+ const {
5
+ parseDependenciesForSCAServices
6
+ } = require('../common/scaParserForGoAndJava')
4
7
 
5
8
  const javaAnalysis = (config, languageFiles) => {
6
9
  languageFiles.JAVA.forEach(file => {
@@ -8,7 +11,12 @@ const javaAnalysis = (config, languageFiles) => {
8
11
  })
9
12
 
10
13
  const javaDeps = buildJavaTree(config, languageFiles.JAVA)
11
- return createJavaTSMessage(javaDeps)
14
+
15
+ if (config.experimental) {
16
+ return parseDependenciesForSCAServices(javaDeps)
17
+ } else {
18
+ return createJavaTSMessage(javaDeps)
19
+ }
12
20
  }
13
21
 
14
22
  const buildJavaTree = (config, files) => {
@@ -14,14 +14,14 @@ const parseBuildDeps = (config, input) => {
14
14
  const preParser = shavedOutput => {
15
15
  let obj = []
16
16
  for (let dep in shavedOutput) {
17
+ shavedOutput[dep] = shaveDependencyType(shavedOutput[dep])
18
+
17
19
  obj.push(
18
20
  shavedOutput[dep]
19
21
  .replace('+-', '+---')
20
22
  .replace('[INFO]', '')
21
23
  .replace('\\-', '\\---')
22
24
  .replace(':jar:', ':')
23
- .replace(':test', '')
24
- .replace(':compile', '')
25
25
  .replace(' +', '+')
26
26
  .replace(' |', '|')
27
27
  .replace(' \\', '\\')
@@ -56,11 +56,29 @@ const preParser = shavedOutput => {
56
56
  return depTree
57
57
  }
58
58
 
59
+ const shaveDependencyType = dep => {
60
+ if (dep.endsWith('\r')) {
61
+ dep = dep.slice(0, -1)
62
+ }
63
+
64
+ if (dep.endsWith(':test')) {
65
+ dep = dep.slice(0, -5)
66
+ }
67
+
68
+ if (dep.endsWith(':compile')) {
69
+ dep = dep.slice(0, -8)
70
+ }
71
+
72
+ if (dep.endsWith(':provided')) {
73
+ dep = dep.slice(0, -9)
74
+ }
75
+
76
+ return dep
77
+ }
78
+
59
79
  const shaveOutput = (gradleDependencyTreeOutput, projectType) => {
60
80
  let shavedOutput = gradleDependencyTreeOutput.split('\n')
61
81
 
62
- // console.log(projectType)
63
-
64
82
  if (projectType === 'maven') {
65
83
  shavedOutput = preParser(shavedOutput)
66
84
  }
@@ -375,7 +393,6 @@ const validateIndentation = shavedOutput => {
375
393
 
376
394
  const parseGradle = (gradleDependencyTreeOutput, config, projectType) => {
377
395
  let shavedOutput = shaveOutput(gradleDependencyTreeOutput, projectType)
378
-
379
396
  if (config.subProject) {
380
397
  let subProject = parseSubProject(shavedOutput)
381
398
  let validatedOutput = validateIndentation(subProject)
@@ -400,5 +417,7 @@ module.exports = {
400
417
  computeRelationToLastElement,
401
418
  addIndentation,
402
419
  computeLevel,
403
- computeIndentation
420
+ computeIndentation,
421
+ shaveDependencyType,
422
+ preParser
404
423
  }
@@ -1,5 +1,6 @@
1
1
  const multiReplace = require('string-multiple-replace')
2
2
  const fs = require('fs')
3
+ const i18n = require('i18n')
3
4
 
4
5
  const readAndParseProjectFile = file => {
5
6
  const filePath = filePathForWindows(file + '/Pipfile')
@@ -23,12 +24,52 @@ const readAndParseLockFile = file => {
23
24
  return parsedPipLock
24
25
  }
25
26
 
26
- const getPythonDeps = config => {
27
+ const readLockFile = file => {
28
+ const filePath = filePathForWindows(file + '/Pipfile.lock')
29
+ const lockFile = fs.readFileSync(filePath, 'utf8')
30
+ let parsedPipLock = JSON.parse(lockFile)
31
+ return parsedPipLock['default']
32
+ }
33
+
34
+ const scaPythonParser = pythonDependencies => {
35
+ let pythonParsedDeps = {}
36
+ for (let key in pythonDependencies) {
37
+ pythonParsedDeps[key] = {}
38
+ pythonParsedDeps[key].version = pythonDependencies[key].version.replace(
39
+ '==',
40
+ ''
41
+ )
42
+ pythonParsedDeps[key].group = null
43
+ pythonParsedDeps[key].name = key
44
+ pythonParsedDeps[key].isProduction = true
45
+ pythonParsedDeps[key].dependencies = []
46
+ pythonParsedDeps[key].directDependency = true
47
+ }
48
+ return pythonParsedDeps
49
+ }
50
+
51
+ const checkForCorrectFiles = languageFiles => {
52
+ if (!languageFiles.includes('Pipfile.lock')) {
53
+ throw new Error(i18n.__('languageAnalysisHasNoLockFile', 'python'))
54
+ }
55
+
56
+ if (!languageFiles.includes('Pipfile')) {
57
+ throw new Error(i18n.__('languageAnalysisProjectFileError', 'python'))
58
+ }
59
+ }
60
+
61
+ const getPythonDeps = (config, languageFiles) => {
27
62
  try {
28
- const parseProject = readAndParseProjectFile(config.file)
29
- const parsePip = readAndParseLockFile(config.file)
63
+ if (config.experimental) {
64
+ let pythonLockFileContents = readLockFile(config.file)
65
+ return scaPythonParser(pythonLockFileContents)
66
+ } else {
67
+ checkForCorrectFiles(languageFiles)
68
+ const parseProject = readAndParseProjectFile(config.file)
69
+ const parsePip = readAndParseLockFile(config.file)
30
70
 
31
- return { pipfileLock: parsePip, pipfilDependanceies: parseProject }
71
+ return { pipfileLock: parsePip, pipfilDependanceies: parseProject }
72
+ }
32
73
  } catch (err) {
33
74
  console.log(err.message.toString())
34
75
  process.exit(1)
@@ -44,6 +85,9 @@ const filePathForWindows = path => {
44
85
 
45
86
  module.exports = {
46
87
  getPythonDeps,
88
+ scaPythonParser,
89
+ readAndParseLockFile,
47
90
  readAndParseProjectFile,
48
- readAndParseLockFile
91
+ checkForCorrectFiles,
92
+ readLockFile
49
93
  }
@@ -1,9 +1,14 @@
1
1
  const { createPythonTSMessage } = require('../common/formatMessage')
2
- const { getPythonDeps } = require('./analysis')
2
+ const { getPythonDeps, secondaryParser } = require('./analysis')
3
3
 
4
4
  const pythonAnalysis = (config, languageFiles) => {
5
5
  const pythonDeps = getPythonDeps(config, languageFiles.PYTHON)
6
- return createPythonTSMessage(pythonDeps)
6
+
7
+ if (config.experimental) {
8
+ return pythonDeps
9
+ } else {
10
+ return createPythonTSMessage(pythonDeps)
11
+ }
7
12
  }
8
13
 
9
14
  module.exports = {
@@ -1,4 +1,5 @@
1
1
  const fs = require('fs')
2
+ const i18n = require('i18n')
2
3
 
3
4
  const readAndParseGemfile = file => {
4
5
  const gemFile = fs.readFileSync(file + '/Gemfile', 'utf8')
@@ -241,15 +242,25 @@ const buildSourceDependencyWithVersion = (
241
242
  return dependencies
242
243
  }
243
244
 
244
- const getRubyDeps = config => {
245
+ const getRubyDeps = (config, languageFiles) => {
245
246
  try {
247
+ checkForCorrectFiles(languageFiles)
246
248
  const parsedGem = readAndParseGemfile(config.file)
247
249
  const parsedLock = readAndParseGemLockFile(config.file)
248
250
 
249
251
  return { gemfilesDependanceies: parsedGem, gemfileLock: parsedLock }
250
252
  } catch (err) {
251
- console.log(err.message)
252
- process.exit(1)
253
+ throw err
254
+ }
255
+ }
256
+
257
+ const checkForCorrectFiles = languageFiles => {
258
+ if (!languageFiles.includes('Gemfile.lock')) {
259
+ throw new Error(i18n.__('languageAnalysisHasNoLockFile', 'ruby'))
260
+ }
261
+
262
+ if (!languageFiles.includes('Gemfile')) {
263
+ throw new Error(i18n.__('languageAnalysisProjectFileError', 'ruby'))
253
264
  }
254
265
  }
255
266
 
@@ -269,5 +280,6 @@ module.exports = {
269
280
  getVersion,
270
281
  getPatchLevel,
271
282
  formatSourceArr,
272
- getSourceArray
283
+ getSourceArray,
284
+ checkForCorrectFiles
273
285
  }
@@ -62,12 +62,12 @@ export function formatScanOutput(scanResults: ScanResultsModel) {
62
62
  })
63
63
  let learnRow: string[] = []
64
64
  let adviceRow = []
65
+ const headerColour = chalk.hex(entry.colour)
65
66
  const headerRow = [
66
- chalk
67
- .hex(entry.colour)
68
- .bold(`CONTRAST-${count.toString().padStart(3, '0')}`),
69
- chalk.hex(entry.colour).bold('-'),
70
- chalk.hex(entry.colour).bold(`[${entry.severity}] ${entry.ruleId}`) +
67
+ headerColour(`CONTRAST-${count.toString().padStart(3, '0')}`),
68
+ headerColour(`-`),
69
+ headerColour(`[${entry.severity}] `) +
70
+ headerColour.bold(`${entry.ruleId}`) +
71
71
  entry.message
72
72
  ]
73
73
 
@@ -104,6 +104,8 @@ export function formatScanOutput(scanResults: ScanResultsModel) {
104
104
  })
105
105
  }
106
106
  printVulnInfo(projectOverview)
107
+
108
+ return projectOverview
107
109
  }
108
110
 
109
111
  function printVulnInfo(projectOverview: any) {
@@ -28,7 +28,11 @@ const createProjectId = async (config, client) => {
28
28
  process.exit(1)
29
29
  return
30
30
  }
31
-
31
+ if (res.statusCode === 429) {
32
+ console.log(i18n.__('exceededFreeTier'))
33
+ process.exit(1)
34
+ return
35
+ }
32
36
  if (res.statusCode === 201) {
33
37
  console.log(i18n.__('projectCreatedScan'))
34
38
  if (config.verbose) {
package/src/scan/scan.ts CHANGED
@@ -47,6 +47,10 @@ export const sendScan = async (config: any) => {
47
47
  )
48
48
  console.log(i18n.__('genericServiceError', res.statusCode))
49
49
  }
50
+ if (res.statusCode === 429) {
51
+ console.log(i18n.__('exceededFreeTier'))
52
+ process.exit(1)
53
+ }
50
54
  if (res.statusCode === 403) {
51
55
  console.log(i18n.__('permissionsError'))
52
56
  process.exit(1)
@@ -1,13 +1,15 @@
1
1
  const paramHandler = require('../utils/paramsUtil/paramHandler')
2
2
  const constants = require('../../src/constants.js')
3
- const parsedCLIOptions = require('../../src/utils/parsedCLIOptions')
4
3
  const path = require('path')
5
4
  const { supportedLanguagesScan } = require('../constants/constants')
6
5
  const i18n = require('i18n')
7
6
  const { scanUsageGuide } = require('./help')
7
+ const parsedCLIOptions = require('../utils/parsedCLIOptions')
8
8
 
9
- const getScanConfig = argv => {
10
- let scanParams = parsedCLIOptions.getCommandLineArgsCustom(
9
+ const getScanConfig = async (contrastConf, command, argv) => {
10
+ let scanParams = await parsedCLIOptions.getCommandLineArgsCustom(
11
+ contrastConf,
12
+ command,
11
13
  argv,
12
14
  constants.commandLineDefinitions.scanOptionDefinitions
13
15
  )