@contrast/contrast 1.0.20 → 1.0.21

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 (35) hide show
  1. package/dist/cliConstants.js +13 -6
  2. package/dist/commands/audit/help.js +2 -1
  3. package/dist/commands/audit/processAudit.js +1 -1
  4. package/dist/commands/fingerprint/fingerprintConfig.js +12 -0
  5. package/dist/commands/fingerprint/processFingerprint.js +14 -0
  6. package/dist/commands/learn/learn.js +9 -0
  7. package/dist/commands/learn/processLearn.js +10 -0
  8. package/dist/common/commonHelp.js +8 -1
  9. package/dist/constants/constants.js +1 -1
  10. package/dist/constants/locales.js +8 -1
  11. package/dist/index.js +8 -0
  12. package/dist/lambda/help.js +2 -1
  13. package/dist/scaAnalysis/scaAnalysis.js +155 -0
  14. package/dist/scan/autoDetection.js +2 -2
  15. package/dist/scan/fileUtils.js +2 -2
  16. package/dist/scan/help.js +2 -1
  17. package/package.json +1 -1
  18. package/src/cliConstants.js +15 -6
  19. package/src/commands/audit/help.js +2 -1
  20. package/src/commands/audit/processAudit.js +1 -1
  21. package/src/commands/fingerprint/fingerprintConfig.js +19 -0
  22. package/src/commands/fingerprint/processFingerprint.js +21 -0
  23. package/src/commands/learn/learn.js +10 -0
  24. package/src/commands/learn/processLearn.js +13 -0
  25. package/src/common/commonHelp.js +11 -1
  26. package/src/constants/constants.js +1 -1
  27. package/src/constants/locales.js +16 -1
  28. package/src/index.ts +11 -0
  29. package/src/lambda/help.ts +2 -1
  30. package/src/scaAnalysis/scaAnalysis.js +206 -0
  31. package/src/scan/autoDetection.js +2 -2
  32. package/src/scan/fileUtils.js +2 -2
  33. package/src/scan/help.js +2 -1
  34. package/dist/commands/scan/sca/scaAnalysis.js +0 -157
  35. package/src/commands/scan/sca/scaAnalysis.js +0 -211
@@ -296,10 +296,6 @@ const auditOptionDefinitions = [
296
296
  '}: ' +
297
297
  i18n.__('constantsIgnoreDev')
298
298
  },
299
- {
300
- name: 'fingerprint',
301
- type: Boolean
302
- },
303
299
  {
304
300
  name: 'save',
305
301
  alias: 's',
@@ -358,6 +354,14 @@ const auditOptionDefinitions = [
358
354
  i18n.__('auditOptionsBranchSummary')
359
355
  }
360
356
  ];
357
+ const fingerprintOptionDefinitions = [
358
+ ...auditOptionDefinitions,
359
+ {
360
+ name: 'depth',
361
+ type: Number,
362
+ description: '{bold ' + i18n.__('constantsOptional') + '}: ' + i18n.__('depthOption')
363
+ }
364
+ ];
361
365
  const mainUsageGuide = commandLineUsage([
362
366
  {
363
367
  header: i18n.__('constantsHeader'),
@@ -379,7 +383,8 @@ const mainUsageGuide = commandLineUsage([
379
383
  { name: i18n.__('auditName'), summary: i18n.__('helpAuditSummary') },
380
384
  { name: i18n.__('versionName'), summary: i18n.__('helpVersionSummary') },
381
385
  { name: i18n.__('configName'), summary: i18n.__('helpConfigSummary') },
382
- { name: i18n.__('helpName'), summary: i18n.__('helpSummary') }
386
+ { name: i18n.__('helpName'), summary: i18n.__('helpSummary') },
387
+ { name: i18n.__('learnName'), summary: i18n.__('helpLearnSummary') }
383
388
  ]
384
389
  },
385
390
  {
@@ -393,7 +398,8 @@ const mainUsageGuide = commandLineUsage([
393
398
  ]
394
399
  },
395
400
  commonHelpLinks()[0],
396
- commonHelpLinks()[1]
401
+ commonHelpLinks()[1],
402
+ commonHelpLinks()[2]
397
403
  ]);
398
404
  const mainDefinition = [{ name: 'command', defaultOption: true }];
399
405
  module.exports = {
@@ -401,6 +407,7 @@ module.exports = {
401
407
  mainUsageGuide,
402
408
  mainDefinition,
403
409
  scanOptionDefinitions,
410
+ fingerprintOptionDefinitions,
404
411
  auditOptionDefinitions,
405
412
  authOptionDefinitions,
406
413
  configOptionDefinitions,
@@ -61,7 +61,8 @@ const auditUsageGuide = commandLineUsage([
61
61
  optionList: constants.commandLineDefinitions.auditAdvancedOptionDefinitionsForHelp
62
62
  },
63
63
  commonHelpLinks()[0],
64
- commonHelpLinks()[1]
64
+ commonHelpLinks()[1],
65
+ commonHelpLinks()[2]
65
66
  ]);
66
67
  module.exports = {
67
68
  auditUsageGuide
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  const auditConfig = require('./auditConfig');
3
3
  const { auditUsageGuide } = require('./help');
4
- const scaController = require('../scan/sca/scaAnalysis');
4
+ const scaController = require('../../scaAnalysis/scaAnalysis');
5
5
  const { sendTelemetryConfigAsObject } = require('../../telemetry/telemetry');
6
6
  const { postRunMessage } = require('../../common/commonHelp');
7
7
  const processAudit = async (contrastConf, argvMain) => {
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ const parsedCLIOptions = require('../../utils/parsedCLIOptions');
3
+ const constants = require('../../cliConstants');
4
+ const paramHandler = require('../../utils/paramsUtil/paramHandler');
5
+ const getFingerprintConfig = async (contrastConf, command, argv) => {
6
+ const fingerprintParameters = await parsedCLIOptions.getCommandLineArgsCustom(contrastConf, command, argv, constants.commandLineDefinitions.fingerprintOptionDefinitions);
7
+ const paramsAuth = paramHandler.getAuth(fingerprintParameters);
8
+ return { ...paramsAuth, ...fingerprintParameters };
9
+ };
10
+ module.exports = {
11
+ getFingerprintConfig
12
+ };
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ const fingerprintConfig = require('./fingerprintConfig');
3
+ const autoDetection = require('../../scan/autoDetection');
4
+ const saveResults = require('../../scan/saveResults');
5
+ const processFingerprint = async (contrastConf, argvMain) => {
6
+ const config = await fingerprintConfig.getFingerprintConfig(contrastConf, 'fingerprint', argvMain);
7
+ let fingerprint = await autoDetection.autoDetectFingerprintInfo(config.file, config.depth);
8
+ let idArray = fingerprint.map(x => x.id);
9
+ await saveResults.writeResultsToFile(fingerprint, 'fingerPrintInfo.json');
10
+ return console.log(idArray);
11
+ };
12
+ module.exports = {
13
+ processFingerprint
14
+ };
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ const open = require('open');
3
+ async function openLearnPage() {
4
+ const url = 'https://www.contrastsecurity.com/developer/learn';
5
+ return open(url);
6
+ }
7
+ module.exports = {
8
+ openLearnPage
9
+ };
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ const { openLearnPage } = require('./learn');
3
+ async function processLearn() {
4
+ console.log('Opening develop central...');
5
+ console.log('If the page does not open you can open it directly via https://www.contrastsecurity.com/developer/learn');
6
+ return openLearnPage();
7
+ }
8
+ module.exports = {
9
+ processLearn
10
+ };
@@ -19,17 +19,24 @@ 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
  };
25
30
  const postRunMessage = commandName => {
26
31
  console.log('\n' + chalk.underline.bold('Other Features:'));
27
32
  if (commandName !== 'scan')
28
- console.log("'contrast scan' to run Contrasts’ industry leading SAST scanner");
33
+ console.log("'contrast scan' to run Contrast's industry leading SAST scanner");
29
34
  if (commandName !== 'audit')
30
35
  console.log("'contrast audit' to find vulnerabilities in your open source dependencies");
31
36
  if (commandName !== 'lambda')
32
37
  console.log("'contrast lambda' to secure your AWS serverless functions");
38
+ if (commandName !== 'learn')
39
+ console.log("'contrast learn' launches Contrast's Secure Code Learning Hub.");
33
40
  };
34
41
  module.exports = {
35
42
  commonHelpLinks,
@@ -12,7 +12,7 @@ const MEDIUM = 'MEDIUM';
12
12
  const HIGH = 'HIGH';
13
13
  const CRITICAL = 'CRITICAL';
14
14
  const APP_NAME = 'contrast';
15
- const APP_VERSION = '1.0.20';
15
+ const APP_VERSION = '1.0.21';
16
16
  const TIMEOUT = 120000;
17
17
  const HIGH_COLOUR = '#ff9900';
18
18
  const CRITICAL_COLOUR = '#e35858';
@@ -121,6 +121,10 @@ const en_locales = () => {
121
121
  versionName: 'version',
122
122
  configName: 'config',
123
123
  helpName: 'help',
124
+ learnName: 'learn',
125
+ helpLearnSummary: 'launches Contrast’s Secure Code Learning Hub.',
126
+ fingerprintName: 'assess repo to see how many languages it can detect. For use in pipeline only.',
127
+ depthOption: 'can set how deep in the file system the cli looks for language files',
124
128
  scanOptionsLanguageSummary: 'Valid values are JAVA, JAVASCRIPT and DOTNET',
125
129
  scanOptionsTimeoutSummary: 'Time in seconds to wait for scan to complete. Default value is 300 seconds.',
126
130
  scanOptionsFileNameSummary: 'Path of the file you want to scan. If no file is specified, Contrast searches for a .jar, .war, .exe or .zip file in the working directory.',
@@ -219,7 +223,10 @@ const en_locales = () => {
219
223
  commonHelpLearnMoreText: ' https://www.contrastsecurity.com/developer ',
220
224
  commonHelpLearnMoreEnterpriseText: ' https://docs.contrastsecurity.com/en/run-contrast-cli.html ',
221
225
  commonHelpJoinDiscussionHeader: chalk.hex('#9DC184')('Join the discussion:'),
222
- commonHelpJoinDiscussionText: ' https://dev.to/codesec',
226
+ commonHelpJoinDiscussionText: ' https://www.contrastsecurity.com/developer/community',
227
+ commonHelpLearnHeader: chalk.hex('#ffe599')('\rWant to UP your game?') +
228
+ " type 'contrast learn'",
229
+ commonHelpLearnText: `\n🎓 Advance your security knowledge and become an ${chalk.hex('#ffd966')('All-star coder')} ⭐ with ${chalk.bold('Contrast Secure Code Learning Hub.')} 😺`,
223
230
  authCommand: {
224
231
  credentialsAccepted: {
225
232
  title: 'Credentials accepted',
package/dist/index.js CHANGED
@@ -9,6 +9,7 @@ const processAudit_1 = require("./commands/audit/processAudit");
9
9
  const auth_1 = require("./commands/auth/auth");
10
10
  const config_1 = require("./commands/config/config");
11
11
  const processScan_1 = require("./commands/scan/processScan");
12
+ const processFingerprint_1 = require("./commands/fingerprint/processFingerprint");
12
13
  const cliConstants_1 = __importDefault(require("./cliConstants"));
13
14
  const constants_1 = require("./constants/constants");
14
15
  const lambda_1 = require("./lambda/lambda");
@@ -16,6 +17,7 @@ const getConfig_1 = require("./utils/getConfig");
16
17
  const versionChecker_1 = require("./common/versionChecker");
17
18
  const errorHandling_1 = require("./common/errorHandling");
18
19
  const telemetry_1 = require("./telemetry/telemetry");
20
+ const processLearn_1 = require("./commands/learn/processLearn");
19
21
  const { commandLineDefinitions: { mainUsageGuide, mainDefinition } } = cliConstants_1.default;
20
22
  const config = (0, getConfig_1.localConfig)(constants_1.APP_NAME, constants_1.APP_VERSION);
21
23
  const getMainOption = () => {
@@ -64,6 +66,12 @@ const start = async () => {
64
66
  if (command === 'audit') {
65
67
  return await (0, processAudit_1.processAudit)(config, argvMain);
66
68
  }
69
+ if (command === 'learn') {
70
+ return (0, processLearn_1.processLearn)();
71
+ }
72
+ if (command === 'fingerprint') {
73
+ return await (0, processFingerprint_1.processFingerprint)(config, argvMain);
74
+ }
67
75
  if (command === 'help' ||
68
76
  argvMain.includes('--help') ||
69
77
  Object.keys(mainOptions).length === 0) {
@@ -82,6 +82,7 @@ const lambdaUsageGuide = (0, command_line_usage_1.default)([
82
82
  ]
83
83
  },
84
84
  (0, commonHelp_1.commonHelpLinks)()[0],
85
- (0, commonHelp_1.commonHelpLinks)()[1]
85
+ (0, commonHelp_1.commonHelpLinks)()[1],
86
+ (0, commonHelp_1.commonHelpLinks)()[2]
86
87
  ]);
87
88
  exports.lambdaUsageGuide = lambdaUsageGuide;
@@ -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
@@ -43,7 +43,8 @@ const scanUsageGuide = commandLineUsage([
43
43
  optionList: constants.commandLineDefinitions.scanAdvancedOptionDefinitionsForHelp
44
44
  },
45
45
  commonHelpLinks()[0],
46
- commonHelpLinks()[1]
46
+ commonHelpLinks()[1],
47
+ commonHelpLinks()[2]
47
48
  ]);
48
49
  module.exports = {
49
50
  scanUsageGuide
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contrast/contrast",
3
- "version": "1.0.20",
3
+ "version": "1.0.21",
4
4
  "description": "Contrast Security's command line tool",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -337,10 +337,6 @@ const auditOptionDefinitions = [
337
337
  '}: ' +
338
338
  i18n.__('constantsIgnoreDev')
339
339
  },
340
- {
341
- name: 'fingerprint',
342
- type: Boolean
343
- },
344
340
  {
345
341
  name: 'save',
346
342
  alias: 's',
@@ -405,6 +401,16 @@ const auditOptionDefinitions = [
405
401
  }
406
402
  ]
407
403
 
404
+ const fingerprintOptionDefinitions = [
405
+ ...auditOptionDefinitions,
406
+ {
407
+ name: 'depth',
408
+ type: Number,
409
+ description:
410
+ '{bold ' + i18n.__('constantsOptional') + '}: ' + i18n.__('depthOption')
411
+ }
412
+ ]
413
+
408
414
  const mainUsageGuide = commandLineUsage([
409
415
  {
410
416
  header: i18n.__('constantsHeader'),
@@ -426,7 +432,8 @@ const mainUsageGuide = commandLineUsage([
426
432
  { name: i18n.__('auditName'), summary: i18n.__('helpAuditSummary') },
427
433
  { name: i18n.__('versionName'), summary: i18n.__('helpVersionSummary') },
428
434
  { name: i18n.__('configName'), summary: i18n.__('helpConfigSummary') },
429
- { name: i18n.__('helpName'), summary: i18n.__('helpSummary') }
435
+ { name: i18n.__('helpName'), summary: i18n.__('helpSummary') },
436
+ { name: i18n.__('learnName'), summary: i18n.__('helpLearnSummary') }
430
437
  ]
431
438
  },
432
439
  {
@@ -440,7 +447,8 @@ const mainUsageGuide = commandLineUsage([
440
447
  ]
441
448
  },
442
449
  commonHelpLinks()[0],
443
- commonHelpLinks()[1]
450
+ commonHelpLinks()[1],
451
+ commonHelpLinks()[2]
444
452
  ])
445
453
 
446
454
  const mainDefinition = [{ name: 'command', defaultOption: true }]
@@ -450,6 +458,7 @@ module.exports = {
450
458
  mainUsageGuide,
451
459
  mainDefinition,
452
460
  scanOptionDefinitions,
461
+ fingerprintOptionDefinitions,
453
462
  auditOptionDefinitions,
454
463
  authOptionDefinitions,
455
464
  configOptionDefinitions,
@@ -62,7 +62,8 @@ const auditUsageGuide = commandLineUsage([
62
62
  constants.commandLineDefinitions.auditAdvancedOptionDefinitionsForHelp
63
63
  },
64
64
  commonHelpLinks()[0],
65
- commonHelpLinks()[1]
65
+ commonHelpLinks()[1],
66
+ commonHelpLinks()[2]
66
67
  ])
67
68
 
68
69
  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
 
@@ -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 develop central...')
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
+ }
@@ -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.21'
18
18
  const TIMEOUT = 120000
19
19
  const HIGH_COLOUR = '#ff9900'
20
20
  const CRITICAL_COLOUR = '#e35858'
@@ -177,6 +177,12 @@ const en_locales = () => {
177
177
  versionName: 'version',
178
178
  configName: 'config',
179
179
  helpName: 'help',
180
+ learnName: 'learn',
181
+ helpLearnSummary: 'launches Contrast’s Secure Code Learning Hub.',
182
+ fingerprintName:
183
+ 'assess repo to see how many languages it can detect. For use in pipeline only.',
184
+ depthOption:
185
+ 'can set how deep in the file system the cli looks for language files',
180
186
  scanOptionsLanguageSummary: 'Valid values are JAVA, JAVASCRIPT and DOTNET',
181
187
  scanOptionsTimeoutSummary:
182
188
  'Time in seconds to wait for scan to complete. Default value is 300 seconds.',
@@ -320,7 +326,16 @@ const en_locales = () => {
320
326
  commonHelpJoinDiscussionHeader: chalk.hex('#9DC184')(
321
327
  'Join the discussion:'
322
328
  ),
323
- commonHelpJoinDiscussionText: ' https://dev.to/codesec',
329
+ commonHelpJoinDiscussionText:
330
+ ' https://www.contrastsecurity.com/developer/community',
331
+ commonHelpLearnHeader:
332
+ chalk.hex('#ffe599')('\rWant to UP your game?') +
333
+ " type 'contrast learn'",
334
+ commonHelpLearnText: `\n🎓 Advance your security knowledge and become an ${chalk.hex(
335
+ '#ffd966'
336
+ )('All-star coder')} ⭐ with ${chalk.bold(
337
+ 'Contrast Secure Code Learning Hub.'
338
+ )} 😺`,
324
339
  authCommand: {
325
340
  credentialsAccepted: {
326
341
  title: 'Credentials accepted',