@contrast/contrast 1.0.0 → 1.0.3

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 (213) hide show
  1. package/.prettierignore +3 -0
  2. package/README.md +115 -78
  3. package/dist/audit/AnalysisEngine.js +37 -0
  4. package/dist/audit/catalogueApplication/catalogueApplication.js +36 -0
  5. package/dist/audit/dotnetAnalysisEngine/index.js +25 -0
  6. package/dist/audit/dotnetAnalysisEngine/parseLockFileContents.js +35 -0
  7. package/dist/audit/dotnetAnalysisEngine/parseProjectFileContents.js +15 -0
  8. package/dist/audit/dotnetAnalysisEngine/readLockFileContents.js +18 -0
  9. package/dist/audit/dotnetAnalysisEngine/readProjectFileContents.js +14 -0
  10. package/dist/audit/dotnetAnalysisEngine/sanitizer.js +9 -0
  11. package/dist/audit/goAnalysisEngine/index.js +17 -0
  12. package/dist/audit/goAnalysisEngine/parseProjectFileContents.js +164 -0
  13. package/dist/audit/goAnalysisEngine/readProjectFileContents.js +21 -0
  14. package/dist/audit/goAnalysisEngine/sanitizer.js +5 -0
  15. package/dist/audit/javaAnalysisEngine/index.js +34 -0
  16. package/dist/audit/javaAnalysisEngine/parseMavenProjectFileContents.js +153 -0
  17. package/dist/audit/javaAnalysisEngine/parseProjectFileContents.js +353 -0
  18. package/dist/audit/javaAnalysisEngine/readProjectFileContents.js +98 -0
  19. package/dist/audit/javaAnalysisEngine/sanitizer.js +5 -0
  20. package/dist/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +24 -0
  21. package/dist/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +24 -0
  22. package/dist/audit/languageAnalysisEngine/checkIdentifiedLanguageHasLockFile.js +35 -0
  23. package/dist/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +23 -0
  24. package/dist/audit/languageAnalysisEngine/commonApi.js +18 -0
  25. package/dist/audit/languageAnalysisEngine/constants.js +20 -0
  26. package/dist/audit/languageAnalysisEngine/filterProjectPath.js +20 -0
  27. package/dist/audit/languageAnalysisEngine/getIdentifiedLanguageInfo.js +25 -0
  28. package/dist/audit/languageAnalysisEngine/getProjectRootFilenames.js +39 -0
  29. package/dist/audit/languageAnalysisEngine/index.js +39 -0
  30. package/dist/audit/languageAnalysisEngine/langugageAnalysisFactory.js +95 -0
  31. package/dist/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +121 -0
  32. package/dist/audit/languageAnalysisEngine/report/checkIgnoreDevDep.js +17 -0
  33. package/dist/audit/languageAnalysisEngine/report/commonReportingFunctions.js +257 -0
  34. package/dist/audit/languageAnalysisEngine/report/newReportingFeature.js +81 -0
  35. package/dist/audit/languageAnalysisEngine/report/reportingFeature.js +133 -0
  36. package/dist/audit/languageAnalysisEngine/sendSnapshot.js +41 -0
  37. package/dist/audit/languageAnalysisEngine/util/capabilities.js +11 -0
  38. package/dist/audit/languageAnalysisEngine/util/generalAPI.js +39 -0
  39. package/dist/audit/languageAnalysisEngine/util/requestUtils.js +14 -0
  40. package/dist/audit/nodeAnalysisEngine/handleNPMLockFileV2.js +40 -0
  41. package/dist/audit/nodeAnalysisEngine/index.js +31 -0
  42. package/dist/audit/nodeAnalysisEngine/parseNPMLockFileContents.js +18 -0
  43. package/dist/audit/nodeAnalysisEngine/parseYarn2LockFileContents.js +51 -0
  44. package/dist/audit/nodeAnalysisEngine/parseYarnLockFileContents.js +18 -0
  45. package/dist/audit/nodeAnalysisEngine/readNPMLockFileContents.js +17 -0
  46. package/dist/audit/nodeAnalysisEngine/readProjectFileContents.js +14 -0
  47. package/dist/audit/nodeAnalysisEngine/readYarnLockFileContents.js +24 -0
  48. package/dist/audit/nodeAnalysisEngine/sanitizer.js +9 -0
  49. package/dist/audit/phpAnalysisEngine/index.js +23 -0
  50. package/dist/audit/phpAnalysisEngine/parseLockFileContents.js +52 -0
  51. package/dist/audit/phpAnalysisEngine/readLockFileContents.js +13 -0
  52. package/dist/audit/phpAnalysisEngine/readProjectFileContents.js +16 -0
  53. package/dist/audit/phpAnalysisEngine/sanitizer.js +5 -0
  54. package/dist/audit/pythonAnalysisEngine/index.js +25 -0
  55. package/dist/audit/pythonAnalysisEngine/parsePipfileLockContents.js +17 -0
  56. package/dist/audit/pythonAnalysisEngine/parseProjectFileContents.js +21 -0
  57. package/dist/audit/pythonAnalysisEngine/readPipfileLockFileContents.js +13 -0
  58. package/dist/audit/pythonAnalysisEngine/readPythonProjectFileContents.js +14 -0
  59. package/dist/audit/pythonAnalysisEngine/sanitizer.js +7 -0
  60. package/dist/audit/rubyAnalysisEngine/index.js +25 -0
  61. package/dist/audit/rubyAnalysisEngine/parseGemfileLockContents.js +176 -0
  62. package/dist/audit/rubyAnalysisEngine/parsedGemfile.js +22 -0
  63. package/dist/audit/rubyAnalysisEngine/readGemfileContents.js +14 -0
  64. package/dist/audit/rubyAnalysisEngine/readGemfileLockContents.js +14 -0
  65. package/dist/audit/rubyAnalysisEngine/sanitizer.js +6 -0
  66. package/dist/commands/audit/auditConfig.js +25 -0
  67. package/dist/commands/audit/auditController.js +31 -0
  68. package/dist/commands/audit/help.js +52 -0
  69. package/dist/commands/audit/processAudit.js +18 -0
  70. package/dist/commands/audit/saveFile.js +11 -0
  71. package/dist/commands/auth/auth.js +20 -2
  72. package/dist/commands/config/config.js +19 -8
  73. package/dist/commands/scan/processScan.js +9 -13
  74. package/dist/common/HTTPClient.js +112 -13
  75. package/dist/common/errorHandling.js +65 -1
  76. package/dist/common/versionChecker.js +30 -0
  77. package/dist/constants/constants.js +4 -2
  78. package/dist/constants/lambda.js +32 -4
  79. package/dist/constants/locales.js +60 -21
  80. package/dist/constants.js +181 -21
  81. package/dist/index.js +50 -23
  82. package/dist/lambda/aws.js +14 -11
  83. package/dist/lambda/help.js +4 -0
  84. package/dist/lambda/lambda.js +50 -27
  85. package/dist/lambda/lambdaUtils.js +72 -0
  86. package/dist/lambda/logUtils.js +11 -1
  87. package/dist/lambda/scanDetailCompletion.js +4 -4
  88. package/dist/lambda/scanRequest.js +11 -5
  89. package/dist/lambda/utils.js +110 -53
  90. package/dist/sbom/generateSbom.js +20 -0
  91. package/dist/scan/autoDetection.js +0 -32
  92. package/dist/scan/fileUtils.js +1 -1
  93. package/dist/scan/help.js +14 -40
  94. package/dist/scan/populateProjectIdAndProjectName.js +5 -0
  95. package/dist/scan/saveResults.js +14 -0
  96. package/dist/scan/scan.js +105 -40
  97. package/dist/scan/scanConfig.js +39 -0
  98. package/dist/scan/scanController.js +19 -16
  99. package/dist/scan/scanResults.js +24 -16
  100. package/dist/utils/commonApi.js +3 -3
  101. package/dist/utils/paramsUtil/commandlineParams.js +1 -20
  102. package/dist/utils/paramsUtil/paramHandler.js +3 -6
  103. package/dist/utils/parsedCLIOptions.js +14 -8
  104. package/dist/utils/requestUtils.js +1 -1
  105. package/dist/utils/saveFile.js +19 -0
  106. package/package.json +26 -21
  107. package/src/audit/AnalysisEngine.js +103 -0
  108. package/src/audit/catalogueApplication/catalogueApplication.js +42 -0
  109. package/src/audit/dotnetAnalysisEngine/index.js +26 -0
  110. package/src/audit/dotnetAnalysisEngine/parseLockFileContents.js +47 -0
  111. package/src/audit/dotnetAnalysisEngine/parseProjectFileContents.js +29 -0
  112. package/src/audit/dotnetAnalysisEngine/readLockFileContents.js +30 -0
  113. package/src/audit/dotnetAnalysisEngine/readProjectFileContents.js +26 -0
  114. package/src/audit/dotnetAnalysisEngine/sanitizer.js +11 -0
  115. package/src/audit/goAnalysisEngine/index.js +18 -0
  116. package/src/audit/goAnalysisEngine/parseProjectFileContents.js +209 -0
  117. package/src/audit/goAnalysisEngine/readProjectFileContents.js +31 -0
  118. package/src/audit/goAnalysisEngine/sanitizer.js +7 -0
  119. package/src/audit/javaAnalysisEngine/index.js +41 -0
  120. package/src/audit/javaAnalysisEngine/parseMavenProjectFileContents.js +222 -0
  121. package/src/audit/javaAnalysisEngine/parseProjectFileContents.js +420 -0
  122. package/src/audit/javaAnalysisEngine/readProjectFileContents.js +141 -0
  123. package/src/audit/javaAnalysisEngine/sanitizer.js +6 -0
  124. package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +35 -0
  125. package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +41 -0
  126. package/src/audit/languageAnalysisEngine/checkIdentifiedLanguageHasLockFile.js +54 -0
  127. package/src/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +32 -0
  128. package/src/audit/languageAnalysisEngine/commonApi.js +20 -0
  129. package/src/audit/languageAnalysisEngine/constants.js +23 -0
  130. package/src/audit/languageAnalysisEngine/filterProjectPath.js +21 -0
  131. package/src/audit/languageAnalysisEngine/getIdentifiedLanguageInfo.js +41 -0
  132. package/src/audit/languageAnalysisEngine/getProjectRootFilenames.js +72 -0
  133. package/src/audit/languageAnalysisEngine/index.js +45 -0
  134. package/src/audit/languageAnalysisEngine/langugageAnalysisFactory.js +126 -0
  135. package/src/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +177 -0
  136. package/src/audit/languageAnalysisEngine/report/checkIgnoreDevDep.js +27 -0
  137. package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.js +303 -0
  138. package/src/audit/languageAnalysisEngine/report/newReportingFeature.js +124 -0
  139. package/src/audit/languageAnalysisEngine/report/reportingFeature.js +190 -0
  140. package/src/audit/languageAnalysisEngine/sendSnapshot.js +51 -0
  141. package/src/audit/languageAnalysisEngine/util/capabilities.js +12 -0
  142. package/src/audit/languageAnalysisEngine/util/generalAPI.js +43 -0
  143. package/src/audit/languageAnalysisEngine/util/requestUtils.js +17 -0
  144. package/src/audit/nodeAnalysisEngine/handleNPMLockFileV2.js +49 -0
  145. package/src/audit/nodeAnalysisEngine/index.js +35 -0
  146. package/src/audit/nodeAnalysisEngine/parseNPMLockFileContents.js +20 -0
  147. package/src/audit/nodeAnalysisEngine/parseYarn2LockFileContents.js +63 -0
  148. package/src/audit/nodeAnalysisEngine/parseYarnLockFileContents.js +26 -0
  149. package/src/audit/nodeAnalysisEngine/readNPMLockFileContents.js +23 -0
  150. package/src/audit/nodeAnalysisEngine/readProjectFileContents.js +27 -0
  151. package/src/audit/nodeAnalysisEngine/readYarnLockFileContents.js +36 -0
  152. package/src/audit/nodeAnalysisEngine/sanitizer.js +11 -0
  153. package/src/audit/phpAnalysisEngine/index.js +27 -0
  154. package/src/audit/phpAnalysisEngine/parseLockFileContents.js +60 -0
  155. package/src/audit/phpAnalysisEngine/readLockFileContents.js +14 -0
  156. package/src/audit/phpAnalysisEngine/readProjectFileContents.js +25 -0
  157. package/src/audit/phpAnalysisEngine/sanitizer.js +4 -0
  158. package/src/audit/pythonAnalysisEngine/index.js +55 -0
  159. package/src/audit/pythonAnalysisEngine/parsePipfileLockContents.js +23 -0
  160. package/src/audit/pythonAnalysisEngine/parseProjectFileContents.js +33 -0
  161. package/src/audit/pythonAnalysisEngine/readPipfileLockFileContents.js +16 -0
  162. package/src/audit/pythonAnalysisEngine/readPythonProjectFileContents.js +22 -0
  163. package/src/audit/pythonAnalysisEngine/sanitizer.js +9 -0
  164. package/src/audit/rubyAnalysisEngine/index.js +30 -0
  165. package/src/audit/rubyAnalysisEngine/parseGemfileLockContents.js +215 -0
  166. package/src/audit/rubyAnalysisEngine/parsedGemfile.js +39 -0
  167. package/src/audit/rubyAnalysisEngine/readGemfileContents.js +18 -0
  168. package/src/audit/rubyAnalysisEngine/readGemfileLockContents.js +17 -0
  169. package/src/audit/rubyAnalysisEngine/sanitizer.js +8 -0
  170. package/src/commands/audit/auditConfig.ts +30 -0
  171. package/src/commands/audit/auditController.ts +31 -0
  172. package/src/commands/audit/help.ts +48 -0
  173. package/src/commands/audit/processAudit.ts +18 -0
  174. package/src/commands/audit/saveFile.ts +6 -0
  175. package/src/commands/auth/auth.js +26 -2
  176. package/src/commands/config/config.js +22 -8
  177. package/src/commands/scan/processScan.js +9 -13
  178. package/src/common/HTTPClient.js +149 -14
  179. package/src/common/errorHandling.ts +85 -2
  180. package/src/common/versionChecker.ts +39 -0
  181. package/src/constants/constants.js +5 -4
  182. package/src/constants/lambda.js +45 -4
  183. package/src/constants/locales.js +76 -26
  184. package/src/constants.js +204 -23
  185. package/src/index.ts +67 -27
  186. package/src/lambda/aws.ts +13 -12
  187. package/src/lambda/help.ts +4 -0
  188. package/src/lambda/lambda.ts +53 -34
  189. package/src/lambda/lambdaUtils.ts +111 -0
  190. package/src/lambda/logUtils.ts +19 -1
  191. package/src/lambda/scanDetailCompletion.ts +4 -4
  192. package/src/lambda/scanRequest.ts +13 -11
  193. package/src/lambda/utils.ts +149 -81
  194. package/src/sbom/generateSbom.ts +17 -0
  195. package/src/scan/autoDetection.js +0 -29
  196. package/src/scan/fileUtils.js +1 -1
  197. package/src/scan/help.js +14 -45
  198. package/src/scan/populateProjectIdAndProjectName.js +5 -0
  199. package/src/scan/saveResults.js +14 -0
  200. package/src/scan/scan.js +127 -58
  201. package/src/scan/scanConfig.js +54 -0
  202. package/src/scan/scanController.js +22 -15
  203. package/src/scan/scanResults.js +32 -19
  204. package/src/utils/commonApi.js +2 -3
  205. package/src/utils/getConfig.ts +2 -0
  206. package/src/utils/paramsUtil/commandlineParams.js +1 -26
  207. package/src/utils/paramsUtil/paramHandler.js +3 -7
  208. package/src/utils/parsedCLIOptions.js +11 -9
  209. package/src/utils/requestUtils.js +1 -1
  210. package/src/utils/saveFile.js +19 -0
  211. package/dist/lambda/scanDetail.js +0 -30
  212. package/dist/scan/fileFinder.js +0 -15
  213. package/dist/utils/paramsUtil/yamlParams.js +0 -6
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.startAudit = void 0;
7
+ const catalogueApplication_1 = require("../../audit/catalogueApplication/catalogueApplication");
8
+ const commonApi_1 = __importDefault(require("../../audit/languageAnalysisEngine/commonApi"));
9
+ const identifyLanguageAE = require('./../../audit/languageAnalysisEngine');
10
+ const languageFactory = require('./../../audit/languageAnalysisEngine/langugageAnalysisFactory');
11
+ const dealWithNoAppId = async (config) => {
12
+ let appID;
13
+ try {
14
+ appID = await commonApi_1.default.returnAppId(config);
15
+ if (!appID && config.applicationName) {
16
+ return await (0, catalogueApplication_1.catalogueApplication)(config);
17
+ }
18
+ }
19
+ catch (e) {
20
+ console.log(e);
21
+ }
22
+ console.log(appID);
23
+ return appID;
24
+ };
25
+ const startAudit = async (config) => {
26
+ if (!config.applicationId) {
27
+ config.applicationId = await dealWithNoAppId(config);
28
+ }
29
+ identifyLanguageAE(config.projectPath, languageFactory, config.applicationId, config);
30
+ };
31
+ exports.startAudit = startAudit;
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.auditUsageGuide = void 0;
7
+ const command_line_usage_1 = __importDefault(require("command-line-usage"));
8
+ const i18n_1 = __importDefault(require("i18n"));
9
+ const constants_1 = __importDefault(require("../../constants"));
10
+ const auditUsageGuide = (0, command_line_usage_1.default)([
11
+ {
12
+ header: i18n_1.default.__('auditHeader'),
13
+ content: [i18n_1.default.__('auditHeaderMessage')]
14
+ },
15
+ {
16
+ header: i18n_1.default.__('constantsPrerequisitesHeader'),
17
+ content: [
18
+ '{bold ' +
19
+ i18n_1.default.__('constantsAuditPrerequisitesContentSupportedLanguages') +
20
+ '}',
21
+ '{bold ' +
22
+ i18n_1.default.__('constantsAuditPrerequisitesContentJava') +
23
+ '}' +
24
+ i18n_1.default.__('constantsAuditPrerequisitesContentMessage'),
25
+ '',
26
+ '{italic ' + i18n_1.default.__('constantsJavaNote') + '}',
27
+ '{italic ' + i18n_1.default.__('constantsJavaNoteGradle') + '}',
28
+ '',
29
+ '{bold ' +
30
+ i18n_1.default.__('constantsAuditPrerequisitesContentDotNet') +
31
+ '}' +
32
+ i18n_1.default.__('constantsAuditPrerequisitesContentDotNetMessage'),
33
+ '{bold ' +
34
+ i18n_1.default.__('constantsAuditPrerequisitesContentLanguageNode') +
35
+ '}' +
36
+ i18n_1.default.__('constantsAuditPrerequisitesContentLanguageNodeMessage'),
37
+ '{bold ' +
38
+ i18n_1.default.__('constantsAuditPrerequisitesContentLanguageRuby') +
39
+ '}' +
40
+ i18n_1.default.__('constantsAuditPrerequisitesContentLanguageRubyMessage'),
41
+ '{bold ' +
42
+ i18n_1.default.__('constantsAuditPrerequisitesContentLanguagePython') +
43
+ '}' +
44
+ i18n_1.default.__('constantsAuditPrerequisitesContentLanguagePythonMessage')
45
+ ]
46
+ },
47
+ {
48
+ header: i18n_1.default.__('constantsAuditOptions'),
49
+ optionList: constants_1.default.commandLineDefinitions.auditOptionDefinitions
50
+ }
51
+ ]);
52
+ exports.auditUsageGuide = auditUsageGuide;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.processAudit = void 0;
4
+ const auditController_1 = require("./auditController");
5
+ const auditConfig_1 = require("./auditConfig");
6
+ const help_1 = require("./help");
7
+ const processAudit = async (argv) => {
8
+ if (argv.indexOf('--help') != -1) {
9
+ printHelpMessage();
10
+ process.exit(1);
11
+ }
12
+ const config = (0, auditConfig_1.getAuditConfig)(argv);
13
+ const auditResults = await (0, auditController_1.startAudit)(config);
14
+ };
15
+ exports.processAudit = processAudit;
16
+ const printHelpMessage = () => {
17
+ console.log(help_1.auditUsageGuide);
18
+ };
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const fs_1 = __importDefault(require("fs"));
7
+ function saveFile(config, rawResults) {
8
+ const fileName = `${config.applicationId}-sbom-cyclonedx.json`;
9
+ fs_1.default.writeFileSync(fileName, JSON.stringify(rawResults));
10
+ }
11
+ exports.default = saveFile;
@@ -7,7 +7,15 @@ const { sleep } = require('../../utils/requestUtils');
7
7
  const i18n = require('i18n');
8
8
  const { returnOra, startSpinner, failSpinner, succeedSpinner } = require('../../utils/oraWrapper');
9
9
  const { TIMEOUT, AUTH_UI_URL } = require('../../constants/constants');
10
- const processAuth = async (config) => {
10
+ const parsedCLIOptions = require('../../utils/parsedCLIOptions');
11
+ const constants = require('../../constants');
12
+ const commandLineUsage = require('command-line-usage');
13
+ const processAuth = async (argv, config) => {
14
+ let authParams = parsedCLIOptions.getCommandLineArgsCustom(argv, constants.commandLineDefinitions.authOptionDefinitions);
15
+ if (authParams.help) {
16
+ console.log(authUsageGuide);
17
+ process.exit(0);
18
+ }
11
19
  const token = uuidv4();
12
20
  const url = `${AUTH_UI_URL}/?token=${token}`;
13
21
  console.log(i18n.__('redirectAuth', url));
@@ -34,7 +42,7 @@ const isAuthComplete = async (token, timeout, config) => {
34
42
  let result = await pollAuthResult(token, client);
35
43
  if (result.statusCode === 200) {
36
44
  succeedSpinner(authSpinner, i18n.__('authSuccessMessage'));
37
- console.log(i18n.__('runScanMessage'));
45
+ console.log(i18n.__('runAuthSuccessMessage'));
38
46
  return result.body;
39
47
  }
40
48
  let endTime = new Date() - startTime;
@@ -56,6 +64,16 @@ const pollAuthResult = async (token, client) => {
56
64
  console.log(err);
57
65
  });
58
66
  };
67
+ const authUsageGuide = commandLineUsage([
68
+ {
69
+ header: i18n.__('authHeader'),
70
+ content: [i18n.__('constantsAuthHeaderContents')]
71
+ },
72
+ {
73
+ header: i18n.__('constantsAuthUsageHeader'),
74
+ content: [i18n.__('constantsAuthUsageContents')]
75
+ }
76
+ ]);
59
77
  module.exports = {
60
78
  processAuth: processAuth
61
79
  };
@@ -1,14 +1,16 @@
1
1
  "use strict";
2
- const commandLineArgs = require('command-line-args');
2
+ const parsedCLIOptions = require('../../utils/parsedCLIOptions');
3
+ const constants = require('../../constants');
4
+ const commandLineUsage = require('command-line-usage');
5
+ const i18n = require('i18n');
3
6
  const processConfig = (argv, config) => {
4
- const options = [{ name: 'clear', alias: 'c', type: Boolean }];
5
7
  try {
6
- const configOptions = commandLineArgs(options, {
7
- argv,
8
- caseInsensitive: true,
9
- camelCase: true
10
- });
11
- if (configOptions.clear) {
8
+ let configParams = parsedCLIOptions.getCommandLineArgsCustom(argv, constants.commandLineDefinitions.configOptionDefinitions);
9
+ if (configParams.help) {
10
+ console.log(configUsageGuide);
11
+ process.exit(0);
12
+ }
13
+ if (configParams.clear) {
12
14
  config.clear();
13
15
  }
14
16
  else {
@@ -19,6 +21,15 @@ const processConfig = (argv, config) => {
19
21
  console.log(e.message.toString());
20
22
  }
21
23
  };
24
+ const configUsageGuide = commandLineUsage([
25
+ {
26
+ header: i18n.__('configHeader')
27
+ },
28
+ {
29
+ content: [i18n.__('constantsConfigUsageContents')],
30
+ optionList: constants.commandLineDefinitions.configOptionDefinitions
31
+ }
32
+ ]);
22
33
  module.exports = {
23
34
  processConfig: processConfig
24
35
  };
@@ -1,23 +1,19 @@
1
1
  "use strict";
2
2
  const { startScan } = require('../../scan/scanController');
3
- const paramHandler = require('../../utils/paramsUtil/paramHandler');
4
3
  const { formatScanOutput } = require('../../scan/scan');
5
4
  const { scanUsageGuide } = require('../../scan/help');
6
- const processScan = async () => {
7
- let getScanSubCommands = paramHandler.getScanSubCommands();
8
- if (getScanSubCommands.help) {
9
- printHelpMessage();
10
- process.exit(1);
11
- }
12
- let scanResults = await startScan();
5
+ const scanConfig = require('../../scan/scanConfig');
6
+ const { saveScanFile } = require('../../utils/saveFile');
7
+ const processScan = async (argvMain) => {
8
+ let config = scanConfig.getScanConfig(argvMain);
9
+ let scanResults = await startScan(config);
13
10
  if (scanResults) {
14
11
  formatScanOutput(scanResults?.projectOverview, scanResults?.scanResultsInstances);
15
12
  }
16
- };
17
- const printHelpMessage = () => {
18
- console.log(scanUsageGuide);
13
+ if (config.save !== undefined) {
14
+ await saveScanFile(config, scanResults);
15
+ }
19
16
  };
20
17
  module.exports = {
21
- processScan,
22
- printHelpMessage
18
+ processScan
23
19
  };
@@ -6,8 +6,9 @@ const { AUTH_CALLBACK_URL } = require('../constants/constants');
6
6
  function HTTPClient(config) {
7
7
  const apiKey = config.apiKey;
8
8
  const authToken = config.authorization;
9
- const superApiKey = config.super_api_key;
10
- const superAuthToken = config.super_authorization;
9
+ this.rejectUnauthorized = !config.ignoreCertErrors;
10
+ const superApiKey = config.superApiKey;
11
+ const superAuthToken = config.superAuthorization;
11
12
  this.requestOptions = {
12
13
  forever: true,
13
14
  json: true,
@@ -65,6 +66,11 @@ HTTPClient.prototype.getSpecificScanResult = function getSpecificScanResult(conf
65
66
  options.url = url;
66
67
  return requestUtils.sendRequest({ method: 'get', options });
67
68
  };
69
+ HTTPClient.prototype.getSpecificScanResultSarif = function getSpecificScanResultSarif(config, scanId) {
70
+ const options = _.cloneDeep(this.requestOptions);
71
+ options.url = createRawOutputURL(config, scanId);
72
+ return requestUtils.sendRequest({ method: 'get', options });
73
+ };
68
74
  HTTPClient.prototype.getScanId = function getScanId(config, codeArtifactId) {
69
75
  const options = _.cloneDeep(this.requestOptions);
70
76
  let url = createGetScanIdURL(config);
@@ -89,9 +95,11 @@ HTTPClient.prototype.createProjectId = function createProjectId(config) {
89
95
  const options = _.cloneDeep(this.requestOptions);
90
96
  options.body = {
91
97
  name: config.name,
92
- archived: 'false',
93
- language: config.language
98
+ archived: 'false'
94
99
  };
100
+ if (config.language) {
101
+ options.body.language = config.language;
102
+ }
95
103
  options.url = createHarmonyProjectsUrl(config);
96
104
  return requestUtils.sendRequest({ method: 'post', options });
97
105
  };
@@ -120,6 +128,58 @@ HTTPClient.prototype.pollForAuth = function pollForAuth(token) {
120
128
  options.body = requestBody;
121
129
  return requestUtils.sendRequest({ method: 'post', options });
122
130
  };
131
+ HTTPClient.prototype.catalogueCommand = function catalogueCommand(config) {
132
+ const options = _.cloneDeep(this.requestOptions);
133
+ let url = createAppCreateURL(config);
134
+ options.url = url;
135
+ let requestBody = {};
136
+ requestBody.name = config.applicationName;
137
+ requestBody.language = config.language.toUpperCase();
138
+ requestBody.appGroups = config.appGroups;
139
+ requestBody.metadata = config.metadata;
140
+ requestBody.tags = config.tags;
141
+ requestBody.code = config.code;
142
+ options.body = requestBody;
143
+ return requestUtils.sendRequest({ method: 'post', options });
144
+ };
145
+ HTTPClient.prototype.sendSnapshot = function sendSnapshot(requestBody, config) {
146
+ const options = _.cloneDeep(this.requestOptions);
147
+ let url = createSnapshotURL(config);
148
+ options.url = url;
149
+ options.body = requestBody;
150
+ return requestUtils.sendRequest({ method: 'post', options });
151
+ };
152
+ HTTPClient.prototype.getReport = function getReport(config) {
153
+ const options = _.cloneDeep(this.requestOptions);
154
+ let url = createReportUrl(config);
155
+ options.url = url;
156
+ return requestUtils.sendRequest({ method: 'get', options });
157
+ };
158
+ HTTPClient.prototype.getSpecificReport = function getSpecificReport(config, reportId) {
159
+ const options = _.cloneDeep(this.requestOptions);
160
+ let url = createSpecificReportUrl(config, reportId);
161
+ options.url = url;
162
+ return requestUtils.sendRequest({ method: 'get', options });
163
+ };
164
+ HTTPClient.prototype.getLibraryVulnerabilities = function getLibraryVulnerabilities(requestBody, config) {
165
+ const options = _.cloneDeep(this.requestOptions);
166
+ let url = createLibraryVulnerabilitiesUrl(config);
167
+ options.url = url;
168
+ options.body = requestBody;
169
+ return requestUtils.sendRequest({ method: 'put', options });
170
+ };
171
+ HTTPClient.prototype.getAppId = function getAppId(config) {
172
+ const options = _.cloneDeep(this.requestOptions);
173
+ let url = createAppNameUrl(config);
174
+ options.url = url;
175
+ return requestUtils.sendRequest({ method: 'get', options });
176
+ };
177
+ HTTPClient.prototype.getDependencyTree = function getReport(orgUuid, appId, reportId) {
178
+ const options = _.cloneDeep(this.requestOptions);
179
+ let url = createGetDependencyTree(options.uri, orgUuid, appId, reportId);
180
+ options.url = url;
181
+ return requestUtils.sendRequest({ method: 'get', options });
182
+ };
123
183
  function getServerlessHost(config = {}) {
124
184
  const originalHost = config?.host || config?.get('host');
125
185
  const host = originalHost?.endsWith('/')
@@ -145,29 +205,41 @@ function createScanResultsGetUrl(config, params, scanId, functionArn) {
145
205
  const { provider, accountId, organizationId } = params;
146
206
  return `${url}/organizations/${organizationId}/providers/${provider}/accounts/${accountId}/scans/${encodedScanId}/resources/${encodedFunctionArn}/results`;
147
207
  }
148
- HTTPClient.prototype.postFunctionScan = async function postFunctionScan(config, parameters, body) {
149
- const url = createScanFunctionPostUrl(config, parameters);
208
+ HTTPClient.prototype.postFunctionScan = async function postFunctionScan(config, params, body) {
209
+ const url = createScanFunctionPostUrl(config, params);
150
210
  const options = { ...this.requestOptions, body, url };
151
211
  return requestUtils.sendRequest({ method: 'post', options });
152
212
  };
153
- HTTPClient.prototype.getScanResources = async function getScanResources(config, parameters, scanId) {
154
- const url = createScanResourcesGetUrl(config, parameters, scanId);
213
+ HTTPClient.prototype.getScanResources = async function getScanResources(config, params, scanId) {
214
+ const url = createScanResourcesGetUrl(config, params, scanId);
155
215
  const options = { ...this.requestOptions, url };
156
216
  return requestUtils.sendRequest({ method: 'get', options });
157
217
  };
158
- HTTPClient.prototype.getFunctionScanResults = async function getFunctionScanResults(config, parameters, scanId, functionArn) {
159
- const url = createScanResultsGetUrl(config, parameters, scanId, functionArn);
218
+ HTTPClient.prototype.getFunctionScanResults = async function getFunctionScanResults(config, params, scanId, functionArn) {
219
+ const url = createScanResultsGetUrl(config, params, scanId, functionArn);
160
220
  const options = { ...this.requestOptions, url };
161
221
  return requestUtils.sendRequest({ method: 'get', options });
162
222
  };
223
+ HTTPClient.prototype.checkLibrary = function checkLibrary(data) {
224
+ const options = _.cloneDeep(this.requestOptions);
225
+ let url = createDataUrl();
226
+ options.url = url;
227
+ options.body = data;
228
+ return requestUtils.sendRequest({ method: 'post', options });
229
+ };
230
+ HTTPClient.prototype.getSbom = function getSbom(config) {
231
+ const options = _.cloneDeep(this.requestOptions);
232
+ options.url = createSbomCycloneDXUrl(config);
233
+ return requestUtils.sendRequest({ method: 'get', options });
234
+ };
163
235
  const createGetScanIdURL = config => {
164
236
  return `${config.host}/Contrast/api/sast/v1/organizations/${config.organizationId}/projects/${config.projectId}/scans/`;
165
237
  };
166
238
  const createScanResultsInstancesURL = (config, scanId) => {
167
- return `${config.host}/Contrast/api/sast/v1/organizations/${config.organizationId}/projects/${config.projectId}/scans/${scanId}/result-instances?sort=severity,asc`;
239
+ return `${config.host}/Contrast/api/sast/v1/organizations/${config.organizationId}/projects/${config.projectId}/scans/${scanId}/result-instances/info?size=50&page=0&last=false&sort=severity,asc`;
168
240
  };
169
- const createRawOutputURL = (config, codeArtifactId) => {
170
- return `${config.host}/Contrast/api/sast/v1/organizations/${config.organizationId}/projects/${config.projectId}/scans/${codeArtifactId}/raw-output`;
241
+ const createRawOutputURL = (config, scanId) => {
242
+ return `${config.host}/Contrast/api/sast/v1/organizations/${config.organizationId}/projects/${config.projectId}/scans/${scanId}/raw-output`;
171
243
  };
172
244
  const createSpecificScanResultURL = (config, scanId) => {
173
245
  return `${config.host}/Contrast/api/sast/v1/organizations/${config.organizationId}/projects/${config.projectId}/scans/${scanId}`;
@@ -187,6 +259,33 @@ const createGlobalPropertiesUrl = protocol => {
187
259
  const pollForAuthUrl = () => {
188
260
  return `${AUTH_CALLBACK_URL}/auth/credentials`;
189
261
  };
262
+ function createSnapshotURL(config) {
263
+ return `${config.host}/Contrast/api/ng/sca/organizations/${config.organizationId}/applications/${config.applicationId}/snapshots`;
264
+ }
265
+ const createAppCreateURL = config => {
266
+ return `${config.host}/Contrast/api/ng/sca/organizations/${config.organizationId}/applications/create`;
267
+ };
268
+ const createAppNameUrl = config => {
269
+ return `${config.host}/Contrast/api/ng/${config.organizationId}/applications/name?filterText=${config.applicationName}`;
270
+ };
271
+ function createLibraryVulnerabilitiesUrl(config) {
272
+ return `${config.host}/Contrast/api/ng/${config.organizationId}/libraries/artifactsByGroupNameVersion`;
273
+ }
274
+ function createReportUrl(config) {
275
+ return `${config.host}/Contrast/api/ng/sca/organizations/${config.organizationId}/applications/${config.applicationId}/reports`;
276
+ }
277
+ function createSpecificReportUrl(config, reportId) {
278
+ return `${config.host}/Contrast/api/ng/sca/organizations/${config.organizationId}/applications/${config.applicationId}/reports/${reportId}?nodesToInclude=PROD`;
279
+ }
280
+ function createDataUrl() {
281
+ return `https://ardy.contrastsecurity.com/production`;
282
+ }
283
+ const createGetDependencyTree = (protocol, orgUuid, appId, reportId) => {
284
+ return `${protocol}/Contrast/api/ng/sca/organizations/${orgUuid}/applications/${appId}/reports/${reportId}`;
285
+ };
286
+ function createSbomCycloneDXUrl(config) {
287
+ return `${config.host}/Contrast/api/ng/${config.organizationId}/applications/${config.applicationId}/libraries/sbom/cyclonedx`;
288
+ }
190
289
  module.exports = HTTPClient;
191
290
  module.exports.pollForAuthUrl = pollForAuthUrl;
192
291
  module.exports.getServerlessHost = getServerlessHost;
@@ -3,8 +3,56 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.getErrorMessage = exports.generalError = exports.hostWarningError = exports.failOptionError = exports.proxyError = exports.forbiddenError = exports.badRequestError = exports.unauthenticatedError = exports.genericError = void 0;
6
+ exports.findCommandOnError = exports.libraryAnalysisError = exports.handleResponseErrors = exports.getErrorMessage = exports.generalError = exports.hostWarningError = exports.failOptionError = exports.proxyError = exports.forbiddenError = exports.badRequestError = exports.unauthenticatedError = exports.genericError = void 0;
7
7
  const i18n_1 = __importDefault(require("i18n"));
8
+ const handleResponseErrors = (res, api) => {
9
+ if (res.statusCode === 400) {
10
+ api === 'catalogue' ? badRequestError(true) : badRequestError(false);
11
+ }
12
+ else if (res.statusCode === 401) {
13
+ unauthenticatedError();
14
+ }
15
+ else if (res.statusCode === 403) {
16
+ forbiddenError();
17
+ }
18
+ else if (res.statusCode === 407) {
19
+ proxyError();
20
+ }
21
+ else {
22
+ if (api === 'snapshot' || api === 'catalogue') {
23
+ snapshotFailureError();
24
+ }
25
+ if (api === 'vulnerabilities') {
26
+ vulnerabilitiesFailureError();
27
+ }
28
+ if (api === 'report') {
29
+ reportFailureError();
30
+ }
31
+ }
32
+ };
33
+ exports.handleResponseErrors = handleResponseErrors;
34
+ const libraryAnalysisError = () => {
35
+ console.log(i18n_1.default.__('libraryAnalysisError'));
36
+ };
37
+ exports.libraryAnalysisError = libraryAnalysisError;
38
+ const snapshotFailureError = () => {
39
+ console.log('\n ******************************** ' +
40
+ i18n_1.default.__('snapshotFailureHeader') +
41
+ ' *********************************\n' +
42
+ i18n_1.default.__('snapshotFailureMessage'));
43
+ };
44
+ const vulnerabilitiesFailureError = () => {
45
+ console.log('\n ******************************** ' +
46
+ i18n_1.default.__('snapshotFailureHeader') +
47
+ ' *********************************\n' +
48
+ i18n_1.default.__('vulnerabilitiesFailureMessage'));
49
+ };
50
+ const reportFailureError = () => {
51
+ console.log('\n ******************************** ' +
52
+ i18n_1.default.__('snapshotFailureHeader') +
53
+ ' *********************************\n' +
54
+ i18n_1.default.__('reportFailureMessage'));
55
+ };
8
56
  const genericError = (missingCliOption) => {
9
57
  console.log(`*************************** ${i18n_1.default.__('yamlMissingParametersHeader')} ***************************\n${missingCliOption}`);
10
58
  console.error(i18n_1.default.__('yamlMissingParametersMessage'));
@@ -23,6 +71,7 @@ const badRequestError = (catalogue) => {
23
71
  exports.badRequestError = badRequestError;
24
72
  const forbiddenError = () => {
25
73
  generalError('forbiddenRequestErrorHeader', 'forbiddenRequestErrorMessage');
74
+ process.exit(1);
26
75
  };
27
76
  exports.forbiddenError = forbiddenError;
28
77
  const proxyError = () => {
@@ -58,3 +107,18 @@ const generalError = (header, message) => {
58
107
  console.log(finalMessage);
59
108
  };
60
109
  exports.generalError = generalError;
110
+ const findCommandOnError = (unknownOptions) => {
111
+ const commandKeywords = {
112
+ auth: 'auth',
113
+ audit: 'audit',
114
+ scan: 'scan',
115
+ lambda: 'lambda',
116
+ config: 'config'
117
+ };
118
+ const containsCommandKeyword = unknownOptions.some(command => commandKeywords[command]);
119
+ if (containsCommandKeyword) {
120
+ const foundCommands = unknownOptions.filter(command => commandKeywords[command]);
121
+ return foundCommands[0];
122
+ }
123
+ };
124
+ exports.findCommandOnError = findCommandOnError;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.isCorrectNodeVersion = exports.findLatestCLIVersion = void 0;
7
+ const latest_version_1 = __importDefault(require("latest-version"));
8
+ const constants_1 = require("../constants/constants");
9
+ const boxen_1 = __importDefault(require("boxen"));
10
+ const chalk_1 = __importDefault(require("chalk"));
11
+ const semver_1 = __importDefault(require("semver"));
12
+ async function findLatestCLIVersion() {
13
+ const latestCLIVersion = await (0, latest_version_1.default)('@contrast/contrast');
14
+ if (semver_1.default.lt(constants_1.APP_VERSION, latestCLIVersion)) {
15
+ const updateAvailableMessage = `Update available ${chalk_1.default.yellow(constants_1.APP_VERSION)} → ${chalk_1.default.green(latestCLIVersion)}`;
16
+ const npmUpdateAvailableCommand = `Run ${chalk_1.default.cyan('npm i @contrast/contrast -g')} to update via npm`;
17
+ const homebrewUpdateAvailableCommand = `Run ${chalk_1.default.cyan('brew install contrastsecurity/tap/contrast')} to update via brew`;
18
+ console.log((0, boxen_1.default)(`${updateAvailableMessage}\n${npmUpdateAvailableCommand}\n\n${homebrewUpdateAvailableCommand}`, {
19
+ titleAlignment: 'center',
20
+ margin: 1,
21
+ padding: 1,
22
+ align: 'center'
23
+ }));
24
+ }
25
+ }
26
+ exports.findLatestCLIVersion = findLatestCLIVersion;
27
+ async function isCorrectNodeVersion(currentVersion) {
28
+ return semver_1.default.satisfies(currentVersion, '>=16.13.2 <17');
29
+ }
30
+ exports.isCorrectNodeVersion = isCorrectNodeVersion;
@@ -12,10 +12,11 @@ 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.0';
15
+ const APP_VERSION = '1.0.3';
16
16
  const TIMEOUT = 120000;
17
17
  const AUTH_UI_URL = 'https://cli-auth.contrastsecurity.com';
18
18
  const AUTH_CALLBACK_URL = 'https://cli-auth-api.contrastsecurity.com';
19
+ const SARIF_FILE = 'SARIF';
19
20
  module.exports = {
20
21
  supportedLanguages: { NODE, DOTNET, JAVA, RUBY, PYTHON, GO, PHP, JAVASCRIPT },
21
22
  LOW,
@@ -26,5 +27,6 @@ module.exports = {
26
27
  APP_NAME,
27
28
  TIMEOUT,
28
29
  AUTH_UI_URL,
29
- AUTH_CALLBACK_URL
30
+ AUTH_CALLBACK_URL,
31
+ SARIF_FILE
30
32
  };
@@ -9,15 +9,43 @@ const lambda = {
9
9
  missingFunctionName: 'Required parameter --function-name is missing.\nRun command with --help to see usage',
10
10
  failedToGetResults: 'Failed to get results',
11
11
  missingResults: 'Missing vulnerabilities',
12
- missingParameter: 'Required function parameter is missing',
13
12
  awsError: 'AWS error',
14
- missingFlagArguments: 'The following flags are missing an arguments:\n%s',
15
- notSupportedFlags: 'The following flags are not supported:\n%s\nRun command with --help to see usage',
13
+ missingFlagArguments: 'The following flags are missing an arguments:\n{{flags}}',
14
+ notSupportedFlags: 'The following flags are not supported:\n{{flags}}\nRun command with --help to see usage',
15
+ layerNotFound: 'The layer {{layerArn}} could not be found. The scan will continue without it',
16
+ noVulnerabilitiesFound: '👏 No vulnerabilities found',
17
+ scanCompleted: '----- Scan completed {{time}}s -----',
18
+ sendingScanRequest: '{{icon}} Sending Lambda Function scan request to Contrast',
19
+ scanRequestedSuccessfully: '{{icon}} Scan requested successfully',
20
+ fetchingConfiguration: '{{icon}} Fetching configuration and policies for Lambda Function {{functionName}}',
21
+ fetchedConfiguration: '{{icon}} Fetched configuration from AWS',
22
+ scanStarted: 'Scan Started',
23
+ scanFailed: 'Scan Failed',
24
+ scanTimedOut: 'Scan timed out',
25
+ loadingFunctionList: 'Loading lambda function list',
26
+ functionsFound: '{{count}} functions found',
27
+ noFunctionsFound: 'No functions found',
28
+ failedToLoadFunctions: 'Faled to load lambda functions',
29
+ availableForScan: '{{icon}} {{count}} available for scan',
30
+ runtimeCount: '----- {{runtime}} ({{count}}) -----',
31
+ whatHappenedTitle: 'What happened:',
32
+ whatHappenedItem: '{{policy}} have:\n{{comments}}\n',
33
+ recommendation: 'Recommendation:',
34
+ vulnerableDependency: 'Vulnerable dependency',
35
+ dependenciesCount: {
36
+ one: '1 Dependency',
37
+ other: '%s Dependencies'
38
+ },
39
+ foundVulnerabilities: {
40
+ one: 'Found 1 vulnerability',
41
+ other: 'Found %s vulnerabilities'
42
+ },
43
+ vulnerableDependencyDescriptions: '{packageName} (v{version}) has {NUM} known {NUM, plural,one{CVE}other{CVEs}}\n {cves}',
16
44
  something_went_wrong: 'Something went wrong',
17
45
  not_found_404: '404 error - Not found',
18
46
  internal_error: 'Internal error',
19
47
  inactive_account: 'Scanning a function of an inactive account is not supported',
20
- not_supported_runtime: 'Scanning resource of runtime "%s" is not supported.\nSupported runtimes: %s',
48
+ not_supported_runtime: 'Scanning resource of runtime "{{runtime}}" is not supported.\nSupported runtimes: {{supportedRuntimes}}',
21
49
  not_supported_onboard_account: 'Scanning a function of onboard account is not supported',
22
50
  scan_lock: 'Other scan is still running. Please wait until the previous scan finishes',
23
51
  unsupported: 'unsupported',