@contrast/contrast 1.0.0

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 (88) hide show
  1. package/README.md +109 -0
  2. package/bin/contrast.js +2 -0
  3. package/dist/commands/auth/auth.js +61 -0
  4. package/dist/commands/config/config.js +24 -0
  5. package/dist/commands/scan/processScan.js +23 -0
  6. package/dist/common/HTTPClient.js +192 -0
  7. package/dist/common/errorHandling.js +60 -0
  8. package/dist/constants/constants.js +30 -0
  9. package/dist/constants/lambda.js +31 -0
  10. package/dist/constants/locales.js +259 -0
  11. package/dist/constants.js +150 -0
  12. package/dist/index.js +56 -0
  13. package/dist/lambda/__mocks__/aws.js +21 -0
  14. package/dist/lambda/__mocks__/lambdaConfig.json +42 -0
  15. package/dist/lambda/arn.js +21 -0
  16. package/dist/lambda/aws.js +169 -0
  17. package/dist/lambda/cliError.js +76 -0
  18. package/dist/lambda/constants.js +11 -0
  19. package/dist/lambda/help.js +75 -0
  20. package/dist/lambda/lambda.js +130 -0
  21. package/dist/lambda/logUtils.js +36 -0
  22. package/dist/lambda/scanDetail.js +30 -0
  23. package/dist/lambda/scanDetailCompletion.js +56 -0
  24. package/dist/lambda/scanRequest.js +93 -0
  25. package/dist/lambda/scanResults.js +16 -0
  26. package/dist/lambda/utils.js +90 -0
  27. package/dist/scan/autoDetection.js +76 -0
  28. package/dist/scan/fileFinder.js +15 -0
  29. package/dist/scan/fileUtils.js +31 -0
  30. package/dist/scan/help.js +68 -0
  31. package/dist/scan/populateProjectIdAndProjectName.js +55 -0
  32. package/dist/scan/scan.js +96 -0
  33. package/dist/scan/scanController.js +54 -0
  34. package/dist/scan/scanResults.js +85 -0
  35. package/dist/utils/commonApi.js +45 -0
  36. package/dist/utils/filterProjectPath.js +20 -0
  37. package/dist/utils/getConfig.js +30 -0
  38. package/dist/utils/oraWrapper.js +20 -0
  39. package/dist/utils/paramsUtil/commandlineParams.js +31 -0
  40. package/dist/utils/paramsUtil/configStoreParams.js +18 -0
  41. package/dist/utils/paramsUtil/envVariableParams.js +10 -0
  42. package/dist/utils/paramsUtil/paramHandler.js +28 -0
  43. package/dist/utils/paramsUtil/yamlParams.js +6 -0
  44. package/dist/utils/parsedCLIOptions.js +13 -0
  45. package/dist/utils/requestUtils.js +18 -0
  46. package/dist/utils/validationCheck.js +26 -0
  47. package/package.json +123 -0
  48. package/src/commands/auth/auth.js +73 -0
  49. package/src/commands/config/config.js +25 -0
  50. package/src/commands/scan/processScan.js +29 -0
  51. package/src/common/HTTPClient.js +269 -0
  52. package/src/common/errorHandling.ts +79 -0
  53. package/src/constants/constants.js +34 -0
  54. package/src/constants/lambda.js +41 -0
  55. package/src/constants/locales.js +381 -0
  56. package/src/constants.js +168 -0
  57. package/src/index.ts +69 -0
  58. package/src/lambda/__mocks__/aws.ts +32 -0
  59. package/src/lambda/__mocks__/lambdaConfig.json +42 -0
  60. package/src/lambda/arn.ts +32 -0
  61. package/src/lambda/aws.ts +247 -0
  62. package/src/lambda/cliError.ts +72 -0
  63. package/src/lambda/constants.ts +11 -0
  64. package/src/lambda/help.ts +76 -0
  65. package/src/lambda/lambda.ts +174 -0
  66. package/src/lambda/logUtils.ts +46 -0
  67. package/src/lambda/scanDetailCompletion.ts +78 -0
  68. package/src/lambda/scanRequest.ts +142 -0
  69. package/src/lambda/scanResults.ts +29 -0
  70. package/src/lambda/utils.ts +125 -0
  71. package/src/scan/autoDetection.js +77 -0
  72. package/src/scan/fileUtils.js +33 -0
  73. package/src/scan/help.js +74 -0
  74. package/src/scan/populateProjectIdAndProjectName.js +62 -0
  75. package/src/scan/scan.js +126 -0
  76. package/src/scan/scanController.js +69 -0
  77. package/src/scan/scanResults.js +96 -0
  78. package/src/utils/commonApi.js +54 -0
  79. package/src/utils/filterProjectPath.js +21 -0
  80. package/src/utils/getConfig.ts +42 -0
  81. package/src/utils/oraWrapper.js +24 -0
  82. package/src/utils/paramsUtil/commandlineParams.js +37 -0
  83. package/src/utils/paramsUtil/configStoreParams.js +19 -0
  84. package/src/utils/paramsUtil/envVariableParams.js +10 -0
  85. package/src/utils/paramsUtil/paramHandler.js +28 -0
  86. package/src/utils/parsedCLIOptions.js +17 -0
  87. package/src/utils/requestUtils.js +22 -0
  88. package/src/utils/validationCheck.js +34 -0
@@ -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.setConfigValues = exports.createConfigFromYaml = exports.localConfig = void 0;
7
+ const conf_1 = __importDefault(require("conf"));
8
+ const localConfig = (name, version) => {
9
+ const config = new conf_1.default({
10
+ configName: name
11
+ });
12
+ config.set('version', version);
13
+ if (!config.has('host')) {
14
+ config.set('host', 'https://ce.contrastsecurity.com/');
15
+ }
16
+ return config;
17
+ };
18
+ exports.localConfig = localConfig;
19
+ const createConfigFromYaml = (yamlPath) => {
20
+ const yamlConfig = {};
21
+ return yamlConfig;
22
+ };
23
+ exports.createConfigFromYaml = createConfigFromYaml;
24
+ const setConfigValues = (config, values) => {
25
+ config.set('apiKey', values.apiKey);
26
+ config.set('organizationId', values.orgId);
27
+ config.set('authorization', values.authHeader);
28
+ values.host ? config.set('host', values.host) : null;
29
+ };
30
+ exports.setConfigValues = setConfigValues;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ const ora = require('ora');
3
+ const returnOra = text => {
4
+ return ora(text);
5
+ };
6
+ const startSpinner = spinner => {
7
+ spinner.start();
8
+ };
9
+ const succeedSpinner = (spinner, text) => {
10
+ spinner.succeed(text);
11
+ };
12
+ const failSpinner = (spinner, text) => {
13
+ spinner.fail(text);
14
+ };
15
+ module.exports = {
16
+ returnOra,
17
+ startSpinner,
18
+ succeedSpinner,
19
+ failSpinner
20
+ };
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ const cliOptions = require('../parsedCLIOptions');
3
+ const parsedCLIOptions = cliOptions.getCommandLineArgs();
4
+ const getAuth = () => {
5
+ let params = {};
6
+ params.apiKey = parsedCLIOptions['apiKey'];
7
+ params.authorization = parsedCLIOptions['authorization'];
8
+ params.host = parsedCLIOptions['host'];
9
+ params.organizationId = parsedCLIOptions['organizationId'];
10
+ return params;
11
+ };
12
+ const getScanParams = () => {
13
+ let scanParams = {};
14
+ scanParams.help = parsedCLIOptions['help'];
15
+ scanParams.file = parsedCLIOptions['file'];
16
+ scanParams.language = parsedCLIOptions['language']
17
+ ? parsedCLIOptions['language'].toUpperCase()
18
+ : parsedCLIOptions['language'];
19
+ scanParams.ff = parsedCLIOptions['ff'];
20
+ scanParams.timeout = parsedCLIOptions['timeout'];
21
+ scanParams.name = parsedCLIOptions['name'];
22
+ scanParams.verbose = parsedCLIOptions['verbose'];
23
+ if (!scanParams.name) {
24
+ scanParams.name = scanParams.file;
25
+ }
26
+ return scanParams;
27
+ };
28
+ module.exports = {
29
+ getScanParams: getScanParams,
30
+ getAuth: getAuth
31
+ };
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ const validationCheck = require('../validationCheck');
3
+ const commonApi = require('../commonApi');
4
+ const config = require('../getConfig');
5
+ const { APP_NAME, APP_VERSION } = require('../../constants/constants');
6
+ const getAuth = () => {
7
+ const ContrastConf = config.localConfig(APP_NAME, APP_VERSION);
8
+ let ContrastConfToUse = {};
9
+ if (validationCheck.checkConfigHasRequiredValues(ContrastConf)) {
10
+ ContrastConfToUse.apiKey = ContrastConf.get('apiKey');
11
+ ContrastConfToUse.organizationId = ContrastConf.get('organizationId');
12
+ ContrastConfToUse.host = commonApi.getValidHost(ContrastConf.get('host'));
13
+ ContrastConfToUse.authorization = ContrastConf.get('authorization');
14
+ ContrastConfToUse.version = ContrastConf.get('version');
15
+ }
16
+ return ContrastConfToUse;
17
+ };
18
+ module.exports = { getAuth: getAuth };
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ const getAuth = () => {
3
+ let params = {};
4
+ params.apiKey = process.env.CONTRAST__API__API_KEY;
5
+ params.authorization = process.env.CONTRAST__API__AUTHORIZATION;
6
+ params.host = process.env.CONTRAST__API__URL;
7
+ params.organizationId = process.env.CONTRAST__API__ORGANIZATION_ID;
8
+ return params;
9
+ };
10
+ module.exports = { getAuth: getAuth };
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ const commandlineAuth = require('./commandlineParams');
3
+ const configStoreParams = require('./configStoreParams');
4
+ const envVariableParams = require('./envVariableParams');
5
+ const { validateAuthParams } = require('../validationCheck');
6
+ const i18n = require('i18n');
7
+ const getAuth = () => {
8
+ let commandLineAuthParamsAuth = commandlineAuth.getAuth();
9
+ let envVariableParamsAuth = envVariableParams.getAuth();
10
+ let configStoreParamsAuth = configStoreParams.getAuth();
11
+ if (validateAuthParams(commandLineAuthParamsAuth)) {
12
+ return commandLineAuthParamsAuth;
13
+ }
14
+ else if (validateAuthParams(envVariableParamsAuth)) {
15
+ return envVariableParamsAuth;
16
+ }
17
+ else if (validateAuthParams(configStoreParamsAuth)) {
18
+ return configStoreParamsAuth;
19
+ }
20
+ else {
21
+ console.log(i18n.__('configNotFound'));
22
+ process.exit(1);
23
+ }
24
+ };
25
+ const getScanSubCommands = () => {
26
+ return commandlineAuth.getScanParams();
27
+ };
28
+ module.exports = { getAuth: getAuth, getScanSubCommands: getScanSubCommands };
@@ -0,0 +1,6 @@
1
+ 'use strict'
2
+ const fs = require('fs')
3
+ const yaml = require('js-yaml')
4
+ const getAuth = yamlPath => {
5
+ const yamlParams = yaml.load(fs.readFileSync(yamlPath, 'utf8'))
6
+ }
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ const constants = require('../constants');
3
+ const commandLineArgs = require('command-line-args');
4
+ const getCommandLineArgs = () => {
5
+ return commandLineArgs(constants.commandLineDefinitions.scanOptionDefinitions, {
6
+ partial: true,
7
+ camelCase: true,
8
+ caseInsensitive: true
9
+ });
10
+ };
11
+ module.exports = {
12
+ getCommandLineArgs: getCommandLineArgs
13
+ };
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ const request = require('request');
3
+ const Promise = require('bluebird');
4
+ Promise.promisifyAll(request);
5
+ function sendRequest({ options, method = 'put' }) {
6
+ return request[`${method}Async`](options.url, options);
7
+ }
8
+ const millisToSeconds = millis => {
9
+ return ((millis % 60000) / 1000).toFixed(0);
10
+ };
11
+ const sleep = ms => {
12
+ return new Promise(resolve => setTimeout(resolve, ms));
13
+ };
14
+ module.exports = {
15
+ sendRequest: sendRequest,
16
+ sleep: sleep,
17
+ millisToSeconds: millisToSeconds
18
+ };
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ const checkConfigHasRequiredValues = store => {
3
+ return (store.has('apiKey') &&
4
+ store.has('organizationId') &&
5
+ store.has('host') &&
6
+ store.has('authorization') &&
7
+ store.has('version'));
8
+ };
9
+ const validateRequiredScanParams = params => {
10
+ return (params.apiKey &&
11
+ params.organizationId &&
12
+ params.host &&
13
+ params.authorization &&
14
+ params.version);
15
+ };
16
+ const validateAuthParams = params => {
17
+ return !!(params.apiKey &&
18
+ params.organizationId &&
19
+ params.host &&
20
+ params.authorization);
21
+ };
22
+ module.exports = {
23
+ checkConfigHasRequiredValues: checkConfigHasRequiredValues,
24
+ validateAuthParams: validateAuthParams,
25
+ validateRequiredScanParams: validateRequiredScanParams
26
+ };
package/package.json ADDED
@@ -0,0 +1,123 @@
1
+ {
2
+ "name": "@contrast/contrast",
3
+ "version": "1.0.0",
4
+ "description": "Contrast Security's command line tool",
5
+ "main": "dist/index.js",
6
+ "bin": {
7
+ "contrast": "./bin/contrast.js"
8
+ },
9
+ "author": "Jamie Mcgurk <jamie.mcgurk@contrastsecurity.com>",
10
+ "contributors": [
11
+ {
12
+ "name": "Chris Dunne",
13
+ "email": "christopher.dunne@contrastsecurity.com"
14
+ },
15
+ {
16
+ "name": "Andrew Shanks",
17
+ "email": "andrew.shanks@contrastsecurity.com"
18
+ }
19
+ ],
20
+ "license": "ISC",
21
+ "scripts": {
22
+ "build": "tsc",
23
+ "test": "jest --testPathIgnorePatterns=./test-integration/",
24
+ "test-int": "jest ./test-integration/scan/",
25
+ "format": "prettier --write \"**/*.{ts,tsx,js,css,scss,json,md,yml}\" .eslintrc.* .babelrc",
26
+ "check-format": "prettier --check \"**/*.{ts,tsx,js,css,scss,json,md,yml}\" .eslintrc.* .babelrc",
27
+ "coverage-local": "nyc --reporter=text mocha './test/**/*.spec.js'",
28
+ "coverage": "yarn test --coverage",
29
+ "lint": "eslint --config .eslintrc.json . --ext .ts",
30
+ "extract-licenses": "node scripts/extract-licenses",
31
+ "test-jest": "jest",
32
+ "lambda-dev": "npx ts-node src/index.ts lambda",
33
+ "dev": "npx ts-node src/index.ts"
34
+ },
35
+ "engines": {
36
+ "node": ">=16.13.2 <17"
37
+ },
38
+ "dependencies": {
39
+ "@aws-sdk/client-iam": "^3.53.0",
40
+ "@aws-sdk/client-lambda": "^3.53.0",
41
+ "@yarnpkg/lockfile": "^1.1.0",
42
+ "adm-zip": "^0.5.9",
43
+ "bluebird": "^3.7.2",
44
+ "chalk": "^4.1.2",
45
+ "command-line-args": "^5.2.1",
46
+ "command-line-usage": "^6.1.1",
47
+ "conf": "^10.1.1",
48
+ "dotenv": "^16.0.0",
49
+ "fast-glob": "^3.2.11",
50
+ "i18n": "^0.14.1",
51
+ "js-yaml": "^4.1.0",
52
+ "lodash": "^4.17.21",
53
+ "log-symbols": "^4.1.0",
54
+ "open": "^8.4.0",
55
+ "ora": "5.4.1",
56
+ "prettyjson": "^1.2.5",
57
+ "request": "^2.88.2",
58
+ "semver": "^7.3.5",
59
+ "string-builder": "^0.1.8",
60
+ "string-multiple-replace": "^1.0.5",
61
+ "tmp": "^0.2.1",
62
+ "xml2js": "^0.4.23",
63
+ "yarn-lockfile": "^1.1.1"
64
+ },
65
+ "devDependencies": {
66
+ "@tsconfig/node16": "^1.0.2",
67
+ "@types/command-line-args": "^5.2.0",
68
+ "@types/command-line-usage": "^5.0.2",
69
+ "@types/i18n": "^0.13.2",
70
+ "@types/jest": "^27.4.1",
71
+ "@types/lodash": "^4.14.181",
72
+ "@typescript-eslint/eslint-plugin": "^5.13.0",
73
+ "@typescript-eslint/parser": "^5.13.0",
74
+ "csv-writer": "^1.6.0",
75
+ "eslint": "^8.8.0",
76
+ "eslint-config-prettier": "^8.3.0",
77
+ "eslint-plugin-prettier": "^4.0.0",
78
+ "husky": "^3.0.9",
79
+ "jest": "^27.4.7",
80
+ "mocha": "^9.2.1",
81
+ "npm-license-crawler": "^0.2.1",
82
+ "nyc": "^15.1.0",
83
+ "pkg": "^5.5.2",
84
+ "prettier": "^1.19.1",
85
+ "tmp": "^0.2.1",
86
+ "ts-jest": "^27.1.3",
87
+ "ts-node": "^10.7.0",
88
+ "typescript": "^4.6.2",
89
+ "uuid": "^8.3.2"
90
+ },
91
+ "resolutions": {
92
+ "faker": "5.5.3",
93
+ "colors": "1.4.0"
94
+ },
95
+ "eslintIgnore": [
96
+ "node_modules"
97
+ ],
98
+ "prettier": {
99
+ "semi": false,
100
+ "singleQuote": true,
101
+ "overrides": [
102
+ {
103
+ "files": [
104
+ ".eslintrc.ng",
105
+ ".babelrc"
106
+ ],
107
+ "options": {
108
+ "parser": "json"
109
+ }
110
+ }
111
+ ]
112
+ },
113
+ "pkg": {
114
+ "scripts": [
115
+ "dist/**/*.js",
116
+ "bin/contrast"
117
+ ],
118
+ "assets": [
119
+ "dist"
120
+ ],
121
+ "outputPath": "binaries"
122
+ }
123
+ }
@@ -0,0 +1,73 @@
1
+ const { v4: uuidv4 } = require('uuid')
2
+ const { setConfigValues } = require('../../utils/getConfig')
3
+ const open = require('open')
4
+ const commonApi = require('../../utils/commonApi')
5
+ const { sleep } = require('../../utils/requestUtils')
6
+ const i18n = require('i18n')
7
+ const {
8
+ returnOra,
9
+ startSpinner,
10
+ failSpinner,
11
+ succeedSpinner
12
+ } = require('../../utils/oraWrapper')
13
+ const { TIMEOUT, AUTH_UI_URL } = require('../../constants/constants')
14
+
15
+ const processAuth = async config => {
16
+ const token = uuidv4()
17
+ const url = `${AUTH_UI_URL}/?token=${token}`
18
+
19
+ console.log(i18n.__('redirectAuth', url))
20
+
21
+ try {
22
+ //start a spinner / progress
23
+ await setTimeout(() => {
24
+ open(url)
25
+ }, 0)
26
+
27
+ const result = await isAuthComplete(token, TIMEOUT, config)
28
+ if (result) {
29
+ setConfigValues(config, result)
30
+ }
31
+ return
32
+ } finally {
33
+ //spinner stop
34
+ }
35
+ }
36
+
37
+ const isAuthComplete = async (token, timeout, config) => {
38
+ const authSpinner = returnOra(i18n.__('authWaitingMessage'))
39
+ startSpinner(authSpinner)
40
+ const client = commonApi.getHttpClient(config)
41
+ let startTime = new Date()
42
+ let complete = false
43
+ while (!complete) {
44
+ let result = await pollAuthResult(token, client)
45
+ if (result.statusCode === 200) {
46
+ succeedSpinner(authSpinner, i18n.__('authSuccessMessage'))
47
+ console.log(i18n.__('runScanMessage'))
48
+ return result.body
49
+ }
50
+ let endTime = new Date() - startTime
51
+ if (endTime > timeout) {
52
+ failSpinner(authSpinner, i18n.__('authTimedOutMessage'))
53
+ process.exit(1)
54
+ return
55
+ }
56
+ }
57
+ }
58
+
59
+ const pollAuthResult = async (token, client) => {
60
+ await sleep(5000)
61
+ return client
62
+ .pollForAuth(token)
63
+ .then(res => {
64
+ return res
65
+ })
66
+ .catch(err => {
67
+ console.log(err)
68
+ })
69
+ }
70
+
71
+ module.exports = {
72
+ processAuth: processAuth
73
+ }
@@ -0,0 +1,25 @@
1
+ const commandLineArgs = require('command-line-args')
2
+
3
+ const processConfig = (argv, config) => {
4
+ const options = [{ name: 'clear', alias: 'c', type: Boolean }]
5
+
6
+ try {
7
+ const configOptions = commandLineArgs(options, {
8
+ argv,
9
+ caseInsensitive: true,
10
+ camelCase: true
11
+ })
12
+ if (configOptions.clear) {
13
+ config.clear()
14
+ } else {
15
+ console.log(JSON.parse(JSON.stringify(config.store)))
16
+ }
17
+ } catch (e) {
18
+ //handle unknown command inputs
19
+ console.log(e.message.toString())
20
+ }
21
+ }
22
+
23
+ module.exports = {
24
+ processConfig: processConfig
25
+ }
@@ -0,0 +1,29 @@
1
+ const { startScan } = require('../../scan/scanController')
2
+ const paramHandler = require('../../utils/paramsUtil/paramHandler')
3
+ const { formatScanOutput } = require('../../scan/scan')
4
+ const { scanUsageGuide } = require('../../scan/help')
5
+
6
+ const processScan = async () => {
7
+ let getScanSubCommands = paramHandler.getScanSubCommands()
8
+ if (getScanSubCommands.help) {
9
+ printHelpMessage()
10
+ process.exit(1)
11
+ }
12
+
13
+ let scanResults = await startScan()
14
+ if (scanResults) {
15
+ formatScanOutput(
16
+ scanResults?.projectOverview,
17
+ scanResults?.scanResultsInstances
18
+ )
19
+ }
20
+ }
21
+
22
+ const printHelpMessage = () => {
23
+ console.log(scanUsageGuide)
24
+ }
25
+
26
+ module.exports = {
27
+ processScan,
28
+ printHelpMessage
29
+ }