@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
@@ -0,0 +1,155 @@
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('./common/treeUpload');
8
+ const auditController = require('../commands/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('../commands/audit/help');
14
+ const repoMode = require('./repoMode');
15
+ const { dotNetAnalysis } = require('./dotnet');
16
+ const { goAnalysis } = require('./go/goAnalysis');
17
+ const { phpAnalysis } = require('./php');
18
+ const { rubyAnalysis } = require('./ruby');
19
+ const { pythonAnalysis } = require('./python');
20
+ const javaAnalysis = require('./java');
21
+ const jsAnalysis = require('./javascript');
22
+ const auditReport = require('./common/auditReport');
23
+ const scaUpload = require('./common/scaServicesUpload');
24
+ const settingsHelper = require('../utils/settingsHelper');
25
+ const chalk = require('chalk');
26
+ const saveResults = require('../scan/saveResults');
27
+ const { convertGenericToTypedReportModelSca } = require('./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
+ filesFound = await autoDetection.autoDetectAuditFilesAndLanguages(config.file);
43
+ autoDetection.dealWithMultiJava(filesFound);
44
+ if (filesFound.length > 1 && pathWithFile) {
45
+ filesFound = filesFound.filter(i => Object.values(i)[0].includes(path.basename(config.fileName)));
46
+ }
47
+ let messageToSend = undefined;
48
+ if (filesFound.length === 1) {
49
+ switch (Object.keys(filesFound[0])[0]) {
50
+ case JAVA:
51
+ config.language = JAVA;
52
+ if (config.mode === 'repo') {
53
+ try {
54
+ return repoMode.buildRepo(config, filesFound[0]);
55
+ }
56
+ catch (e) {
57
+ throw new Error('Unable to build in repository mode. Check your project file');
58
+ }
59
+ }
60
+ else {
61
+ messageToSend = await javaAnalysis.javaAnalysis(config, filesFound[0]);
62
+ }
63
+ break;
64
+ case JAVASCRIPT:
65
+ messageToSend = await jsAnalysis.jsAnalysis(config, filesFound[0]);
66
+ config.language = NODE;
67
+ break;
68
+ case PYTHON:
69
+ messageToSend = pythonAnalysis(config, filesFound[0]);
70
+ config.language = PYTHON;
71
+ break;
72
+ case RUBY:
73
+ messageToSend = rubyAnalysis(config, filesFound[0]);
74
+ config.language = RUBY;
75
+ break;
76
+ case PHP:
77
+ messageToSend = phpAnalysis(config, filesFound[0]);
78
+ config.language = PHP;
79
+ break;
80
+ case GO:
81
+ messageToSend = goAnalysis(config, filesFound[0]);
82
+ config.language = GO;
83
+ break;
84
+ case DOTNET:
85
+ if (config.experimental) {
86
+ console.log(`${chalk.bold('\n.NET project found\n')} Language type is unsupported.`);
87
+ return;
88
+ }
89
+ else {
90
+ messageToSend = dotNetAnalysis(config, filesFound[0]);
91
+ config.language = DOTNET;
92
+ break;
93
+ }
94
+ default:
95
+ console.log('No supported language detected in project path');
96
+ return;
97
+ }
98
+ if (!config.applicationId) {
99
+ config.applicationId = await auditController.dealWithNoAppId(config);
100
+ }
101
+ if (config.experimental) {
102
+ console.log('');
103
+ const reportSpinner = returnOra(i18n.__('auditSCAAnalysisBegins'));
104
+ startSpinner(reportSpinner);
105
+ const { reportArray, reportId } = await scaUpload.scaTreeUpload(messageToSend, config);
106
+ const reportModelLibraryList = convertGenericToTypedReportModelSca(reportArray);
107
+ auditReport.processAuditReport(config, reportModelLibraryList);
108
+ succeedSpinner(reportSpinner, i18n.__('auditSCAAnalysisComplete'));
109
+ if (config.save !== undefined) {
110
+ await auditSave.auditSave(config, reportId);
111
+ }
112
+ else {
113
+ console.log('Use contrast audit --save to generate an SBOM');
114
+ }
115
+ const endTime = performance.now() - startTime;
116
+ const scanDurationMs = endTime - startTime;
117
+ console.log(`----- completed in ${(scanDurationMs / 1000).toFixed(2)}s -----`);
118
+ }
119
+ else {
120
+ console.log('');
121
+ const reportSpinner = returnOra(i18n.__('auditSCAAnalysisBegins'));
122
+ startSpinner(reportSpinner);
123
+ const snapshotResponse = await treeUpload.commonSendSnapShot(messageToSend, config);
124
+ await pollForSnapshotCompletion(config, snapshotResponse.id, reportSpinner);
125
+ succeedSpinner(reportSpinner, i18n.__('auditSCAAnalysisComplete'));
126
+ await vulnerabilityReportV2(config, snapshotResponse.id);
127
+ if (config.save !== undefined) {
128
+ await auditSave.auditSave(config);
129
+ }
130
+ else {
131
+ console.log('\nUse contrast audit --save to generate an SBOM');
132
+ }
133
+ const endTime = performance.now() - startTime;
134
+ const scanDurationMs = endTime - startTime;
135
+ console.log(`----- completed in ${(scanDurationMs / 1000).toFixed(2)}s -----`);
136
+ }
137
+ }
138
+ else {
139
+ if (filesFound.length === 0) {
140
+ console.log(i18n.__('languageAnalysisNoLanguage'));
141
+ console.log(i18n.__('languageAnalysisNoLanguageHelpLine'));
142
+ throw new Error();
143
+ }
144
+ else {
145
+ console.log(chalk.bold(`\nMultiple language files detected \n`));
146
+ filesFound.forEach(file => {
147
+ console.log(`${Object.keys(file)[0]} : `, Object.values(file)[0]);
148
+ });
149
+ throw new Error(`Please use --file to audit one language only. \nExample: contrast audit --file package-lock.json`);
150
+ }
151
+ }
152
+ };
153
+ module.exports = {
154
+ processSca
155
+ };
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  const i18n = require('i18n');
3
3
  const fileFinder = require('./fileUtils');
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 => {
@@ -10,7 +10,7 @@ const findFile = async () => {
10
10
  onlyFiles: true
11
11
  });
12
12
  };
13
- const findAllFiles = async (filePath) => {
13
+ const findAllFiles = async (filePath, depth = 2) => {
14
14
  const result = await fg([
15
15
  '**/pom.xml',
16
16
  '**/build.gradle',
@@ -22,7 +22,7 @@ const findAllFiles = async (filePath) => {
22
22
  '**/go.mod'
23
23
  ], {
24
24
  dot: false,
25
- deep: 2,
25
+ deep: depth,
26
26
  onlyFiles: true,
27
27
  absolute: true,
28
28
  cwd: filePath ? filePath : process.cwd()
package/dist/scan/help.js CHANGED
@@ -4,6 +4,9 @@ const i18n = require('i18n');
4
4
  const constants = require('../cliConstants');
5
5
  const { commonHelpLinks } = require('../common/commonHelp');
6
6
  const scanUsageGuide = commandLineUsage([
7
+ {
8
+ header: i18n.__('constantsHeader')
9
+ },
7
10
  {
8
11
  header: i18n.__('scanHeader')
9
12
  },
@@ -43,7 +46,8 @@ const scanUsageGuide = commandLineUsage([
43
46
  optionList: constants.commandLineDefinitions.scanAdvancedOptionDefinitionsForHelp
44
47
  },
45
48
  commonHelpLinks()[0],
46
- commonHelpLinks()[1]
49
+ commonHelpLinks()[1],
50
+ commonHelpLinks()[2]
47
51
  ]);
48
52
  module.exports = {
49
53
  scanUsageGuide
@@ -11,9 +11,9 @@ const getSettings = async (config) => {
11
11
  const isSCAServicesAvailable = async (config) => {
12
12
  const client = commonApi.getHttpClient(config);
13
13
  return client
14
- .scaServiceIngests(config)
14
+ .scaServiceHealth(config)
15
15
  .then(res => {
16
- return res.statusCode !== 403;
16
+ return res.body.status === 'UP';
17
17
  })
18
18
  .catch(err => {
19
19
  console.log(err);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contrast/contrast",
3
- "version": "1.0.20",
3
+ "version": "1.0.22",
4
4
  "description": "Contrast Security's command line tool",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -212,6 +212,7 @@ const scanOptionDefinitions = [
212
212
 
213
213
  const authOptionDefinitions = [
214
214
  ...sharedConnectionOptionDefinitions,
215
+ ...sharedCertOptionDefinitions,
215
216
  {
216
217
  name: 'help',
217
218
  alias: 'h',
@@ -337,10 +338,6 @@ const auditOptionDefinitions = [
337
338
  '}: ' +
338
339
  i18n.__('constantsIgnoreDev')
339
340
  },
340
- {
341
- name: 'fingerprint',
342
- type: Boolean
343
- },
344
341
  {
345
342
  name: 'save',
346
343
  alias: 's',
@@ -405,6 +402,16 @@ const auditOptionDefinitions = [
405
402
  }
406
403
  ]
407
404
 
405
+ const fingerprintOptionDefinitions = [
406
+ ...auditOptionDefinitions,
407
+ {
408
+ name: 'depth',
409
+ type: Number,
410
+ description:
411
+ '{bold ' + i18n.__('constantsOptional') + '}: ' + i18n.__('depthOption')
412
+ }
413
+ ]
414
+
408
415
  const mainUsageGuide = commandLineUsage([
409
416
  {
410
417
  header: i18n.__('constantsHeader'),
@@ -421,12 +428,13 @@ const mainUsageGuide = commandLineUsage([
421
428
  header: i18n.__('constantsCommands'),
422
429
  content: [
423
430
  { name: i18n.__('authName'), summary: i18n.__('helpAuthSummary') },
431
+ { name: i18n.__('configName'), summary: i18n.__('helpConfigSummary') },
432
+ { name: i18n.__('versionName'), summary: i18n.__('helpVersionSummary') },
433
+ { name: i18n.__('auditName'), summary: i18n.__('helpAuditSummary') },
424
434
  { name: i18n.__('scanName'), summary: i18n.__('helpScanSummary') },
425
435
  { name: i18n.__('lambdaName'), summary: i18n.__('helpLambdaSummary') },
426
- { name: i18n.__('auditName'), summary: i18n.__('helpAuditSummary') },
427
- { name: i18n.__('versionName'), summary: i18n.__('helpVersionSummary') },
428
- { name: i18n.__('configName'), summary: i18n.__('helpConfigSummary') },
429
- { name: i18n.__('helpName'), summary: i18n.__('helpSummary') }
436
+ { name: i18n.__('helpName'), summary: i18n.__('helpSummary') },
437
+ { name: i18n.__('learnName'), summary: i18n.__('helpLearnSummary') }
430
438
  ]
431
439
  },
432
440
  {
@@ -440,7 +448,8 @@ const mainUsageGuide = commandLineUsage([
440
448
  ]
441
449
  },
442
450
  commonHelpLinks()[0],
443
- commonHelpLinks()[1]
451
+ commonHelpLinks()[1],
452
+ commonHelpLinks()[2]
444
453
  ])
445
454
 
446
455
  const mainDefinition = [{ name: 'command', defaultOption: true }]
@@ -450,6 +459,7 @@ module.exports = {
450
459
  mainUsageGuide,
451
460
  mainDefinition,
452
461
  scanOptionDefinitions,
462
+ fingerprintOptionDefinitions,
453
463
  auditOptionDefinitions,
454
464
  authOptionDefinitions,
455
465
  configOptionDefinitions,
@@ -4,6 +4,9 @@ const constants = require('../../cliConstants')
4
4
  const { commonHelpLinks } = require('../../common/commonHelp')
5
5
 
6
6
  const auditUsageGuide = commandLineUsage([
7
+ {
8
+ header: i18n.__('constantsHeader')
9
+ },
7
10
  {
8
11
  header: i18n.__('auditHeader'),
9
12
  content: [i18n.__('auditHeaderMessage')]
@@ -62,7 +65,8 @@ const auditUsageGuide = commandLineUsage([
62
65
  constants.commandLineDefinitions.auditAdvancedOptionDefinitionsForHelp
63
66
  },
64
67
  commonHelpLinks()[0],
65
- commonHelpLinks()[1]
68
+ commonHelpLinks()[1],
69
+ commonHelpLinks()[2]
66
70
  ])
67
71
 
68
72
  module.exports = {
@@ -1,6 +1,6 @@
1
1
  const auditConfig = require('./auditConfig')
2
2
  const { auditUsageGuide } = require('./help')
3
- const scaController = require('../scan/sca/scaAnalysis')
3
+ const scaController = require('../../scaAnalysis/scaAnalysis')
4
4
  const { sendTelemetryConfigAsObject } = require('../../telemetry/telemetry')
5
5
  const { postRunMessage } = require('../../common/commonHelp')
6
6
 
@@ -101,6 +101,11 @@ const authUsageGuide = commandLineUsage([
101
101
  {
102
102
  header: i18n.__('constantsAuthUsageHeader'),
103
103
  content: [i18n.__('constantsAuthUsageContents')]
104
+ },
105
+ {
106
+ header: i18n.__('constantsAdvancedOptions'),
107
+ optionList: constants.commandLineDefinitions.authOptionDefinitions,
108
+ hide: ['organization-id', 'api-key', 'authorization', 'host']
104
109
  }
105
110
  ])
106
111
 
@@ -0,0 +1,19 @@
1
+ const parsedCLIOptions = require('../../utils/parsedCLIOptions')
2
+ const constants = require('../../cliConstants')
3
+ const paramHandler = require('../../utils/paramsUtil/paramHandler')
4
+
5
+ const getFingerprintConfig = async (contrastConf, command, argv) => {
6
+ const fingerprintParameters = await parsedCLIOptions.getCommandLineArgsCustom(
7
+ contrastConf,
8
+ command,
9
+ argv,
10
+ constants.commandLineDefinitions.fingerprintOptionDefinitions
11
+ )
12
+ const paramsAuth = paramHandler.getAuth(fingerprintParameters)
13
+
14
+ return { ...paramsAuth, ...fingerprintParameters }
15
+ }
16
+
17
+ module.exports = {
18
+ getFingerprintConfig
19
+ }
@@ -0,0 +1,21 @@
1
+ const fingerprintConfig = require('./fingerprintConfig')
2
+ const autoDetection = require('../../scan/autoDetection')
3
+ const saveResults = require('../../scan/saveResults')
4
+ const processFingerprint = async (contrastConf, argvMain) => {
5
+ const config = await fingerprintConfig.getFingerprintConfig(
6
+ contrastConf,
7
+ 'fingerprint',
8
+ argvMain
9
+ )
10
+ let fingerprint = await autoDetection.autoDetectFingerprintInfo(
11
+ config.file,
12
+ config.depth
13
+ )
14
+ let idArray = fingerprint.map(x => x.id)
15
+ await saveResults.writeResultsToFile(fingerprint, 'fingerPrintInfo.json')
16
+ return console.log(idArray)
17
+ }
18
+
19
+ module.exports = {
20
+ processFingerprint
21
+ }
@@ -0,0 +1,10 @@
1
+ const open = require('open')
2
+
3
+ async function openLearnPage() {
4
+ const url = 'https://www.contrastsecurity.com/developer/learn'
5
+ return open(url)
6
+ }
7
+
8
+ module.exports = {
9
+ openLearnPage
10
+ }
@@ -0,0 +1,13 @@
1
+ const { openLearnPage } = require('./learn')
2
+
3
+ async function processLearn() {
4
+ console.log('Opening Contrast’s Secure Code Learning Hub...')
5
+ console.log(
6
+ 'If the page does not open you can open it directly via https://www.contrastsecurity.com/developer/learn'
7
+ )
8
+ return openLearnPage()
9
+ }
10
+
11
+ module.exports = {
12
+ processLearn
13
+ }
@@ -254,6 +254,13 @@ HTTPClient.prototype.scaServiceIngests = function scaServiceIngests(config) {
254
254
  return requestUtils.sendRequest({ method: 'get', options })
255
255
  }
256
256
 
257
+ HTTPClient.prototype.scaServiceHealth = function scaServiceIngests(config) {
258
+ const options = _.cloneDeep(this.requestOptions)
259
+ let url = createScaServiceHealthURL(config)
260
+ options.url = url
261
+ return requestUtils.sendRequest({ method: 'get', options })
262
+ }
263
+
257
264
  HTTPClient.prototype.getReportById = function getReportById(config, reportId) {
258
265
  const options = _.cloneDeep(this.requestOptions)
259
266
  if (config.ignoreDev) {
@@ -474,6 +481,10 @@ function createScaServiceIngestsURL(config) {
474
481
  return `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/applications/${config.applicationId}/libraries/ingests`
475
482
  }
476
483
 
484
+ function createScaServiceHealthURL(config) {
485
+ return `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/health`
486
+ }
487
+
477
488
  function createScaServiceIngestURL(config) {
478
489
  let baseUrl = `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/applications/${config.applicationId}/libraries/ingests/tree`
479
490
  baseUrl = config.track ? baseUrl.concat('?persist=true') : baseUrl
@@ -19,6 +19,11 @@ const commonHelpLinks = () => {
19
19
  i18n.__('commonHelpLearnMoreEnterpriseHeader') +
20
20
  i18n.__('commonHelpLearnMoreEnterpriseText')
21
21
  ]
22
+ },
23
+ {
24
+ content: [
25
+ i18n.__('commonHelpLearnHeader') + i18n.__('commonHelpLearnText')
26
+ ]
22
27
  }
23
28
  ]
24
29
  }
@@ -27,7 +32,7 @@ const postRunMessage = commandName => {
27
32
  console.log('\n' + chalk.underline.bold('Other Features:'))
28
33
  if (commandName !== 'scan')
29
34
  console.log(
30
- "'contrast scan' to run Contrasts’ industry leading SAST scanner"
35
+ "'contrast scan' to run Contrast's industry leading SAST scanner"
31
36
  )
32
37
  if (commandName !== 'audit')
33
38
  console.log(
@@ -35,6 +40,11 @@ const postRunMessage = commandName => {
35
40
  )
36
41
  if (commandName !== 'lambda')
37
42
  console.log("'contrast lambda' to secure your AWS serverless functions")
43
+
44
+ if (commandName !== 'learn')
45
+ console.log(
46
+ "'contrast learn' launches Contrast's Secure Code Learning Hub."
47
+ )
38
48
  }
39
49
 
40
50
  module.exports = {
@@ -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.20'
17
+ const APP_VERSION = '1.0.22'
18
18
  const TIMEOUT = 120000
19
19
  const HIGH_COLOUR = '#ff9900'
20
20
  const CRITICAL_COLOUR = '#e35858'
@@ -66,6 +66,7 @@ const lambda = {
66
66
  'Scanning a function of an inactive account is not supported',
67
67
  not_supported_runtime:
68
68
  'Scanning resource of runtime "{{runtime}}" is not supported.\nSupported runtimes: {{supportedRuntimes}}',
69
+ not_supported_lambda: 'This function cannot be scanned',
69
70
  not_supported_onboard_account:
70
71
  'Scanning a function of onboard account is not supported',
71
72
  scan_lock:
@@ -1,5 +1,6 @@
1
1
  const { lambda } = require('./lambda')
2
2
  const chalk = require('chalk')
3
+ const { APP_VERSION } = require('./constants')
3
4
 
4
5
  const en_locales = () => {
5
6
  return {
@@ -83,7 +84,7 @@ const en_locales = () => {
83
84
  ' FAIL - Results detected vulnerabilities over accepted severity level',
84
85
  constantsSeverity:
85
86
  'Use with "contrast scan --fail --severity high" or "contrast audit --fail --severity high". Set the severity level to detect vulnerabilities or dependencies. Severity levels are critical, high, medium, low or note.',
86
- constantsHeader: 'Contrast CLI',
87
+ constantsHeader: `Contrast CLI @ v${APP_VERSION}`,
87
88
  configHeader2: 'Config options',
88
89
  clearHeader: '-c, --clear',
89
90
  clearContent: 'Removes stored credentials',
@@ -160,13 +161,13 @@ const en_locales = () => {
160
161
  scanErrorFileMessage:
161
162
  'We only accept the following file types: \nJava - .jar, .war \nJavaScript - .js or .zip files',
162
163
  helpAuthSummary:
163
- 'Authenticate Contrast using your Github or Google account',
164
+ 'Authenticate Contrast using your Github or Google account OR include credentials if you are an existing licensed Contrast user.',
164
165
  helpAuditSummary:
165
- 'Searches for a suitable file in the working directory to perform a security audit of dependencies and returns the results. [Contrast audit --help (for options).]',
166
+ 'Searches for a suitable file in the working directory to perform a security audit of dependencies and returns the results. \n[audit --help for options] Java, .NET, Node, Ruby, Python, Go, PHP are supported. ',
166
167
  helpScanSummary:
167
- 'Searches for a .jar, .war, .js, or .zip file in the working directory, uploads files for analysis, and returns the results. [For further help/options, enter scan --help]',
168
+ 'Searches for a .jar, .war, .js, or .zip file in the working directory, uploads files for analysis, and returns the results. \n[scan --help for options] Java, .NET, .NET Core, JavaScript are supported. ',
168
169
  helpLambdaSummary:
169
- 'Performs a static security scan on an AWS lambda function. lambda --help (for options)',
170
+ 'Performs a static security scan on an AWS lambda function. [lambda --help for options] AWS Lambda - Java & Python are supported. ',
170
171
  helpVersionSummary: 'Displays version of Contrast CLI',
171
172
  helpConfigSummary: 'Displays stored credentials',
172
173
  helpSummary: 'Displays usage guide',
@@ -177,6 +178,12 @@ const en_locales = () => {
177
178
  versionName: 'version',
178
179
  configName: 'config',
179
180
  helpName: 'help',
181
+ learnName: 'learn',
182
+ helpLearnSummary: 'Launches Contrast’s Secure Code Learning Hub.',
183
+ fingerprintName:
184
+ 'assess repo to see how many languages it can detect. For use in pipeline only.',
185
+ depthOption:
186
+ 'can set how deep in the file system the cli looks for language files',
180
187
  scanOptionsLanguageSummary: 'Valid values are JAVA, JAVASCRIPT and DOTNET',
181
188
  scanOptionsTimeoutSummary:
182
189
  'Time in seconds to wait for scan to complete. Default value is 300 seconds.',
@@ -196,7 +203,7 @@ const en_locales = () => {
196
203
  chalk.bold('\ncontrast audit') +
197
204
  ' to find vulnerabilities in your open source dependencies.' +
198
205
  '\nSupports Java, .NET, Node, Ruby, Python, Go and PHP.' +
199
- '\nOur CLI runs native build tools to generate a complete dependency tree.' +
206
+ '\n\nOur CLI runs native build tools to generate a complete dependency tree.' +
200
207
  '\nIf you are running on untrusted code, consider running in a sandbox.\n' +
201
208
  chalk.bold('\ncontrast lambda') +
202
209
  ' to secure your AWS serverless functions. \nSupports Java and Python \n' +
@@ -210,7 +217,7 @@ const en_locales = () => {
210
217
  searchingScanFileDirectory: 'Searching for file to scan from %s...',
211
218
  searchingAuditFileDirectory:
212
219
  'Searching for package manager files from %s...',
213
- scanHeader: 'Contrast Scan CLI',
220
+ scanHeader: `Contrast Scan CLI`,
214
221
  authHeader: 'Auth',
215
222
  lambdaHeader: 'Contrast Lambda CLI',
216
223
  lambdaSummary:
@@ -251,7 +258,7 @@ const en_locales = () => {
251
258
  'An error has occurred when trying to get the Project Id please check your internet connection or provide the Project Id manually',
252
259
  internalServerErrorHeader: '500 error - Internal server error',
253
260
  resourceLockedErrorHeader: '423 error - Resource is locked',
254
- auditHeader: 'Contrast audit help',
261
+ auditHeader: 'Contrast Audit CLI',
255
262
  auditHeaderMessage:
256
263
  "Use 'contrast audit' to analyze a project’s dependencies for vulnerabilities.",
257
264
  constantsAuditPrerequisitesContentSupportedLanguages:
@@ -320,12 +327,21 @@ const en_locales = () => {
320
327
  commonHelpJoinDiscussionHeader: chalk.hex('#9DC184')(
321
328
  'Join the discussion:'
322
329
  ),
323
- commonHelpJoinDiscussionText: ' https://dev.to/codesec',
330
+ commonHelpJoinDiscussionText:
331
+ ' https://www.contrastsecurity.com/developer/community',
332
+ commonHelpLearnHeader:
333
+ chalk.hex('#ffe599')('\r Want to UP your game?') +
334
+ " type 'contrast learn'",
335
+ commonHelpLearnText: `\n💰 Advance your security knowledge and become an ${chalk.hex(
336
+ '#ffd966'
337
+ )('All-star coder')} ⭐ with ${chalk.bold(
338
+ 'Contrast Secure Code Learning Hub.'
339
+ )} 😺`,
324
340
  authCommand: {
325
341
  credentialsAccepted: {
326
- title: 'Credentials accepted',
327
- body: 'Now run contrast audit, lambda or scan',
328
- extra: 'Or contrast help for full list of commands'
342
+ title: 'Credentials successfully saved',
343
+ body: `\n${chalk.bold('Contrast CLI')}`,
344
+ extra: 'Scan, secure and ship your code in minutes.'
329
345
  },
330
346
  credentialsMissing: {
331
347
  title: 'Credentials missing',
package/src/index.ts CHANGED
@@ -5,6 +5,7 @@ import { processAudit } from './commands/audit/processAudit'
5
5
  import { processAuth } from './commands/auth/auth'
6
6
  import { processConfig } from './commands/config/config'
7
7
  import { processScan } from './commands/scan/processScan'
8
+ import { processFingerprint } from './commands/fingerprint/processFingerprint'
8
9
  import constants from './cliConstants'
9
10
  import { APP_NAME, APP_VERSION } from './constants/constants'
10
11
  import { processLambda } from './lambda/lambda'
@@ -15,6 +16,7 @@ import {
15
16
  } from './common/versionChecker'
16
17
  import { findCommandOnError } from './common/errorHandling'
17
18
  import { sendTelemetryConfigAsConfObj } from './telemetry/telemetry'
19
+ import { processLearn } from './commands/learn/processLearn'
18
20
  const {
19
21
  commandLineDefinitions: { mainUsageGuide, mainDefinition }
20
22
  } = constants
@@ -82,6 +84,14 @@ const start = async () => {
82
84
  return await processAudit(config, argvMain)
83
85
  }
84
86
 
87
+ if (command === 'learn') {
88
+ return processLearn()
89
+ }
90
+
91
+ if (command === 'fingerprint') {
92
+ return await processFingerprint(config, argvMain)
93
+ }
94
+
85
95
  if (
86
96
  command === 'help' ||
87
97
  argvMain.includes('--help') ||
@@ -3,6 +3,9 @@ import i18n from 'i18n'
3
3
  import { commonHelpLinks } from '../common/commonHelp'
4
4
 
5
5
  const lambdaUsageGuide = commandLineUsage([
6
+ {
7
+ header: i18n.__('constantsHeader')
8
+ },
6
9
  {
7
10
  header: i18n.__('lambdaHeader'),
8
11
  content: [i18n.__('lambdaSummary')]
@@ -82,7 +85,8 @@ const lambdaUsageGuide = commandLineUsage([
82
85
  ]
83
86
  },
84
87
  commonHelpLinks()[0],
85
- commonHelpLinks()[1]
88
+ commonHelpLinks()[1],
89
+ commonHelpLinks()[2]
86
90
  ])
87
91
 
88
92
  export { lambdaUsageGuide }