@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,126 @@
1
+ const commonApi = require('../utils/commonApi.js')
2
+ const fileUtils = require('../scan/fileUtils')
3
+ const allowedFileTypes = ['.jar', '.war', '.js', '.zip']
4
+ const i18n = require('i18n')
5
+ const AdmZip = require('adm-zip')
6
+ const oraWrapper = require('../utils/oraWrapper')
7
+ const { supportedLanguages } = require('../constants/constants')
8
+
9
+ const isFileAllowed = scanOption => {
10
+ let valid = false
11
+ allowedFileTypes.forEach(fileType => {
12
+ if (scanOption.endsWith(fileType)) {
13
+ valid = true
14
+ }
15
+ })
16
+ return valid
17
+ }
18
+
19
+ const sendScan = async config => {
20
+ if (!isFileAllowed(config.file)) {
21
+ console.log(i18n.__('scanErrorFileMessage'))
22
+ process.exit(9)
23
+ } else {
24
+ fileUtils.checkFilePermissions(config.file)
25
+ const client = commonApi.getHttpClient(config)
26
+
27
+ const startUploadSpinner = oraWrapper.returnOra(i18n.__('uploadingScan'))
28
+ oraWrapper.startSpinner(startUploadSpinner)
29
+
30
+ return await client
31
+ .sendArtifact(config)
32
+ .then(res => {
33
+ if (res.statusCode === 201) {
34
+ oraWrapper.succeedSpinner(
35
+ startUploadSpinner,
36
+ i18n.__('uploadingScanSuccessful')
37
+ )
38
+ if (config.verbose) {
39
+ console.log(i18n.__('responseMessage', res.body))
40
+ }
41
+ return res.body.id
42
+ } else {
43
+ oraWrapper.failSpinner(
44
+ startUploadSpinner,
45
+ i18n.__('uploadingScanFail')
46
+ )
47
+ process.exit(1)
48
+ }
49
+ })
50
+ .catch(err => {
51
+ console.log(err)
52
+ })
53
+ }
54
+ }
55
+
56
+ const zipValidator = configToUse => {
57
+ if (configToUse.file.endsWith('.zip')) {
58
+ let zipFileName = configToUse.file.split('/').pop()
59
+ try {
60
+ let zip = new AdmZip(configToUse.file)
61
+ let zipEntries = zip.getEntries()
62
+ zipEntries.forEach(function(zipEntry) {
63
+ if (
64
+ !zipEntry.entryName.includes('._') &&
65
+ !zipEntry.entryName.includes('/.')
66
+ ) {
67
+ if (!zipEntry.isDirectory) {
68
+ if (!zipEntry.entryName.endsWith('.js')) {
69
+ console.log(i18n.__('scanZipError', zipFileName))
70
+ process.exit(1)
71
+ }
72
+ }
73
+ }
74
+ })
75
+ configToUse.language = supportedLanguages.JAVASCRIPT
76
+ } catch {
77
+ console.log(i18n.__('zipFileException'))
78
+ }
79
+ }
80
+ }
81
+
82
+ const formatScanOutput = (overview, results) => {
83
+ console.log()
84
+ console.log('Here are your top priorities to fix')
85
+ console.log()
86
+
87
+ results.content.forEach(entry => {
88
+ console.log(entry.severity, 'ID:', entry.id)
89
+ console.log(
90
+ entry.ruleId,
91
+ 'in',
92
+ entry.locations[0]?.physicalLocation.artifactLocation.uri,
93
+ '@',
94
+ entry.codeFlows[0]?.threadFlows[0]?.locations[0]?.location
95
+ ?.physicalLocation?.region?.startLine
96
+ )
97
+ console.log()
98
+ })
99
+
100
+ const totalVulnerabilities =
101
+ overview.critical +
102
+ overview.high +
103
+ overview.medium +
104
+ overview.low +
105
+ overview.note
106
+
107
+ console.log(`Found ${totalVulnerabilities} vulnerabilities`)
108
+ console.log(
109
+ i18n.__(
110
+ 'foundDetailedVulnerabilities',
111
+ overview.critical,
112
+ overview.high,
113
+ overview.medium,
114
+ overview.low,
115
+ overview.note
116
+ )
117
+ )
118
+ }
119
+
120
+ module.exports = {
121
+ sendScan: sendScan,
122
+ allowedFileTypes: allowedFileTypes,
123
+ isFileAllowed: isFileAllowed,
124
+ formatScanOutput: formatScanOutput,
125
+ zipValidator: zipValidator
126
+ }
@@ -0,0 +1,69 @@
1
+ const i18n = require('i18n')
2
+ const {
3
+ returnOra,
4
+ startSpinner,
5
+ succeedSpinner
6
+ } = require('../utils/oraWrapper')
7
+ const populateProjectIdAndProjectName = require('./populateProjectIdAndProjectName')
8
+ const scan = require('./scan')
9
+ const scanResults = require('./scanResults')
10
+ const autoDetection = require('./autoDetection')
11
+ const paramHandler = require('../utils/paramsUtil/paramHandler')
12
+ const fileFunctions = require('./fileUtils')
13
+
14
+ const getTimeout = config => {
15
+ if (config.timeout) {
16
+ return config.timeout
17
+ } else {
18
+ if (config.verbose) {
19
+ console.log('Timeout set to 5 minutes')
20
+ }
21
+ return 300
22
+ }
23
+ }
24
+
25
+ const startScan = async () => {
26
+ let paramsAuth = paramHandler.getAuth()
27
+ let getScanSubCommands = paramHandler.getScanSubCommands()
28
+ const configToUse = { ...paramsAuth, ...getScanSubCommands }
29
+ if (configToUse.file === undefined || configToUse.file === null) {
30
+ await autoDetection.autoDetectFileAndLanguage(configToUse)
31
+ } else {
32
+ if (fileFunctions.fileExists(configToUse.file)) {
33
+ scan.zipValidator(configToUse)
34
+ autoDetection.assignLanguage([configToUse.file], configToUse)
35
+ } else {
36
+ console.log(i18n.__('fileNotExist'))
37
+ process.exit(0)
38
+ }
39
+ }
40
+
41
+ if (!configToUse.projectId) {
42
+ configToUse.projectId = await populateProjectIdAndProjectName.populateProjectId(
43
+ configToUse
44
+ )
45
+ }
46
+ const codeArtifactId = await scan.sendScan(configToUse)
47
+
48
+ if (!configToUse.ff) {
49
+ const startScanSpinner = returnOra('Contrast Scan started')
50
+ startSpinner(startScanSpinner)
51
+ const scanDetail = await scanResults.returnScanResults(
52
+ configToUse,
53
+ codeArtifactId,
54
+ getTimeout(configToUse),
55
+ startScanSpinner
56
+ )
57
+ const scanResultsInstances = await scanResults.returnScanResultsInstances(
58
+ configToUse,
59
+ scanDetail.id
60
+ )
61
+ succeedSpinner(startScanSpinner, 'Contrast Scan complete')
62
+ const projectOverview = await scanResults.returnScanProjectById(configToUse)
63
+ return { projectOverview, scanResultsInstances }
64
+ }
65
+ }
66
+
67
+ module.exports = {
68
+ startScan: startScan
69
+ }
@@ -0,0 +1,96 @@
1
+ const commonApi = require('../utils/commonApi')
2
+ const requestUtils = require('../../src/utils/requestUtils')
3
+ const i18n = require('i18n')
4
+ const oraFunctions = require('../utils/oraWrapper')
5
+
6
+ const getScanId = async (config, codeArtifactId, client) => {
7
+ return client
8
+ .getScanId(config, codeArtifactId)
9
+ .then(res => {
10
+ return res.body.id
11
+ })
12
+ .catch(err => {
13
+ console.log(err)
14
+ })
15
+ }
16
+
17
+ const pollScanResults = async (config, scanId, client) => {
18
+ await requestUtils.sleep(5000)
19
+ return client
20
+ .getSpecificScanResult(config, scanId)
21
+ .then(res => {
22
+ return res
23
+ })
24
+ .catch(err => {
25
+ console.log(err)
26
+ })
27
+ }
28
+
29
+ const returnScanResults = async (
30
+ config,
31
+ codeArtifactId,
32
+ timeout,
33
+ startScanSpinner
34
+ ) => {
35
+ const client = commonApi.getHttpClient(config)
36
+ let scanId = await getScanId(config, codeArtifactId, client)
37
+ let startTime = new Date()
38
+ let complete = false
39
+ while (!complete) {
40
+ let result = await pollScanResults(config, scanId, client)
41
+ if (JSON.stringify(result.statusCode) == 200) {
42
+ if (result.body.status === 'COMPLETED') {
43
+ complete = true
44
+ return result.body
45
+ }
46
+ if (result.body.status === 'FAILED') {
47
+ complete = true
48
+ oraFunctions.failSpinner(startScanSpinner, 'Contrast Scan Failed.')
49
+ process.exit(1)
50
+ }
51
+ }
52
+ let endTime = new Date() - startTime
53
+ if (requestUtils.millisToSeconds(endTime) > timeout) {
54
+ oraFunctions.failSpinner(
55
+ startScanSpinner,
56
+ 'Contrast Scan timed out at the specified ' + timeout + ' seconds.'
57
+ )
58
+ console.log('Please try again, allowing more time.')
59
+ process.exit(1)
60
+ }
61
+ }
62
+ }
63
+
64
+ const returnScanResultsInstances = async (config, scanId) => {
65
+ const client = commonApi.getHttpClient(config)
66
+ let result
67
+ try {
68
+ result = await client.getScanResultsInstances(config, scanId)
69
+ if (JSON.stringify(result.statusCode) == 200) {
70
+ return result.body
71
+ }
72
+ } catch (e) {
73
+ console.log(e.message.toString())
74
+ }
75
+ }
76
+
77
+ const returnScanProjectById = async config => {
78
+ const client = commonApi.getHttpClient(config)
79
+ let result
80
+ try {
81
+ result = await client.getScanProjectById(config)
82
+ if (JSON.stringify(result.statusCode) == 200) {
83
+ return result.body
84
+ }
85
+ } catch (e) {
86
+ console.log(e.message.toString())
87
+ }
88
+ }
89
+
90
+ module.exports = {
91
+ getScanId: getScanId,
92
+ returnScanResults: returnScanResults,
93
+ pollScanResults: pollScanResults,
94
+ returnScanResultsInstances: returnScanResultsInstances,
95
+ returnScanProjectById: returnScanProjectById
96
+ }
@@ -0,0 +1,54 @@
1
+ const HttpClient = require('./../common/HTTPClient')
2
+ const {
3
+ badRequestError,
4
+ unauthenticatedError,
5
+ forbiddenError,
6
+ proxyError,
7
+ hostWarningError,
8
+ genericError
9
+ } = require('../common/errorHandling')
10
+
11
+ const handleResponseErrors = (res, api, hostPresent) => {
12
+ if (res.statusCode === 400) {
13
+ api === 'catalogue' ? badRequestError(true) : badRequestError(false)
14
+ } else if (res.statusCode === 401) {
15
+ unauthenticatedError()
16
+ } else if (res.statusCode === 403) {
17
+ forbiddenError()
18
+ } else if (res.statusCode === 407) {
19
+ proxyError()
20
+ } else {
21
+ hostPresent === false ? hostWarningError() : genericError()
22
+ }
23
+ }
24
+
25
+ const getProtocol = host => {
26
+ const hasProtocol =
27
+ host.toLowerCase().includes('https://') ||
28
+ host.toLowerCase().includes('http://')
29
+ return hasProtocol ? host : 'https://' + host
30
+ }
31
+
32
+ const getPath = host => {
33
+ const hasContrastPath = host.toLowerCase().endsWith('/contrast')
34
+ return hasContrastPath
35
+ ? host.toLowerCase().substring(0, host.length - 9)
36
+ : host.replace(/\/*$/, '')
37
+ }
38
+
39
+ const getValidHost = host => {
40
+ const correctProtocol = getProtocol(host)
41
+ return getPath(correctProtocol)
42
+ }
43
+
44
+ const getHttpClient = config => {
45
+ return new HttpClient(config)
46
+ }
47
+
48
+ module.exports = {
49
+ getPath: getPath,
50
+ getValidHost: getValidHost,
51
+ getProtocol: getProtocol,
52
+ handleResponseErrors: handleResponseErrors,
53
+ getHttpClient: getHttpClient
54
+ }
@@ -0,0 +1,21 @@
1
+ const path = require('path')
2
+
3
+ function resolveFilePath(filepath) {
4
+ if (filepath[0] === '~') {
5
+ return path.join(process.env.HOME, filepath.slice(1))
6
+ }
7
+ return filepath
8
+ }
9
+
10
+ const returnProjectPath = () => {
11
+ if (process.env.PWD !== (undefined || null || 'undefined')) {
12
+ return process.env.PWD
13
+ } else {
14
+ return process.argv[process.argv.indexOf('--project_path') + 1]
15
+ }
16
+ }
17
+
18
+ module.exports = {
19
+ returnProjectPath: returnProjectPath,
20
+ resolveFilePath: resolveFilePath
21
+ }
@@ -0,0 +1,42 @@
1
+ import Conf from 'conf'
2
+
3
+ type ContrastConfOptions = Partial<{
4
+ version: string
5
+ host: string
6
+ apiKey: string
7
+ orgId: string
8
+ authHeader: string
9
+ }>
10
+
11
+ type ContrastConf = Conf<ContrastConfOptions>
12
+
13
+ const localConfig = (name: string, version: string) => {
14
+ const config: ContrastConf = new Conf<ContrastConfOptions>({
15
+ configName: name
16
+ })
17
+ config.set('version', version)
18
+ if (!config.has('host')) {
19
+ config.set('host', 'https://ce.contrastsecurity.com/')
20
+ }
21
+ return config
22
+ }
23
+
24
+ const createConfigFromYaml = (yamlPath: string) => {
25
+ const yamlConfig = {}
26
+ return yamlConfig
27
+ }
28
+
29
+ const setConfigValues = (config: ContrastConf, values: ContrastConfOptions) => {
30
+ config.set('apiKey', values.apiKey)
31
+ config.set('organizationId', values.orgId)
32
+ config.set('authorization', values.authHeader)
33
+ values.host ? config.set('host', values.host) : null
34
+ }
35
+
36
+ export {
37
+ localConfig,
38
+ createConfigFromYaml,
39
+ setConfigValues,
40
+ ContrastConf,
41
+ ContrastConfOptions
42
+ }
@@ -0,0 +1,24 @@
1
+ const ora = require('ora')
2
+
3
+ const returnOra = text => {
4
+ return ora(text)
5
+ }
6
+
7
+ const startSpinner = spinner => {
8
+ spinner.start()
9
+ }
10
+
11
+ const succeedSpinner = (spinner, text) => {
12
+ spinner.succeed(text)
13
+ }
14
+
15
+ const failSpinner = (spinner, text) => {
16
+ spinner.fail(text)
17
+ }
18
+
19
+ module.exports = {
20
+ returnOra,
21
+ startSpinner,
22
+ succeedSpinner,
23
+ failSpinner
24
+ }
@@ -0,0 +1,37 @@
1
+ const cliOptions = require('../parsedCLIOptions')
2
+ const parsedCLIOptions = cliOptions.getCommandLineArgs()
3
+
4
+ const getAuth = () => {
5
+ let params = {}
6
+
7
+ params.apiKey = parsedCLIOptions['apiKey']
8
+ params.authorization = parsedCLIOptions['authorization']
9
+ params.host = parsedCLIOptions['host']
10
+ params.organizationId = parsedCLIOptions['organizationId']
11
+ return params
12
+ }
13
+
14
+ const getScanParams = () => {
15
+ let scanParams = {}
16
+ scanParams.help = parsedCLIOptions['help']
17
+ scanParams.file = parsedCLIOptions['file']
18
+ scanParams.language = parsedCLIOptions['language']
19
+ ? parsedCLIOptions['language'].toUpperCase()
20
+ : parsedCLIOptions['language']
21
+ scanParams.ff = parsedCLIOptions['ff']
22
+ scanParams.timeout = parsedCLIOptions['timeout']
23
+ scanParams.name = parsedCLIOptions['name']
24
+ scanParams.verbose = parsedCLIOptions['verbose']
25
+
26
+ // if no name, take the full file path and use it as the project name
27
+ if (!scanParams.name) {
28
+ scanParams.name = scanParams.file
29
+ }
30
+
31
+ return scanParams
32
+ }
33
+
34
+ module.exports = {
35
+ getScanParams: getScanParams,
36
+ getAuth: getAuth
37
+ }
@@ -0,0 +1,19 @@
1
+ const validationCheck = require('../validationCheck')
2
+ const commonApi = require('../commonApi')
3
+ const config = require('../getConfig')
4
+ const { APP_NAME, APP_VERSION } = require('../../constants/constants')
5
+
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
+
19
+ module.exports = { getAuth: getAuth }
@@ -0,0 +1,10 @@
1
+ const getAuth = () => {
2
+ let params = {}
3
+ params.apiKey = process.env.CONTRAST__API__API_KEY
4
+ params.authorization = process.env.CONTRAST__API__AUTHORIZATION
5
+ params.host = process.env.CONTRAST__API__URL
6
+ params.organizationId = process.env.CONTRAST__API__ORGANIZATION_ID
7
+ return params
8
+ }
9
+
10
+ module.exports = { getAuth: getAuth }
@@ -0,0 +1,28 @@
1
+ const commandlineAuth = require('./commandlineParams')
2
+ const configStoreParams = require('./configStoreParams')
3
+ const envVariableParams = require('./envVariableParams')
4
+ const { validateAuthParams } = require('../validationCheck')
5
+ const i18n = require('i18n')
6
+
7
+ const getAuth = () => {
8
+ let commandLineAuthParamsAuth = commandlineAuth.getAuth()
9
+ let envVariableParamsAuth = envVariableParams.getAuth()
10
+ let configStoreParamsAuth = configStoreParams.getAuth()
11
+
12
+ if (validateAuthParams(commandLineAuthParamsAuth)) {
13
+ return commandLineAuthParamsAuth
14
+ } else if (validateAuthParams(envVariableParamsAuth)) {
15
+ return envVariableParamsAuth
16
+ } else if (validateAuthParams(configStoreParamsAuth)) {
17
+ return configStoreParamsAuth
18
+ } else {
19
+ console.log(i18n.__('configNotFound'))
20
+ process.exit(1)
21
+ }
22
+ }
23
+
24
+ const getScanSubCommands = () => {
25
+ return commandlineAuth.getScanParams()
26
+ }
27
+
28
+ module.exports = { getAuth: getAuth, getScanSubCommands: getScanSubCommands }
@@ -0,0 +1,17 @@
1
+ const constants = require('../constants')
2
+ const commandLineArgs = require('command-line-args')
3
+
4
+ const getCommandLineArgs = () => {
5
+ return commandLineArgs(
6
+ constants.commandLineDefinitions.scanOptionDefinitions,
7
+ {
8
+ partial: true,
9
+ camelCase: true,
10
+ caseInsensitive: true
11
+ }
12
+ )
13
+ }
14
+
15
+ module.exports = {
16
+ getCommandLineArgs: getCommandLineArgs
17
+ }
@@ -0,0 +1,22 @@
1
+ const request = require('request')
2
+ const Promise = require('bluebird')
3
+
4
+ Promise.promisifyAll(request)
5
+
6
+ function sendRequest({ options, method = 'put' }) {
7
+ return request[`${method}Async`](options.url, options)
8
+ }
9
+
10
+ const millisToSeconds = millis => {
11
+ return ((millis % 60000) / 1000).toFixed(0)
12
+ }
13
+
14
+ const sleep = ms => {
15
+ return new Promise(resolve => setTimeout(resolve, ms))
16
+ }
17
+
18
+ module.exports = {
19
+ sendRequest: sendRequest,
20
+ sleep: sleep,
21
+ millisToSeconds: millisToSeconds
22
+ }
@@ -0,0 +1,34 @@
1
+ const checkConfigHasRequiredValues = store => {
2
+ return (
3
+ store.has('apiKey') &&
4
+ store.has('organizationId') &&
5
+ store.has('host') &&
6
+ store.has('authorization') &&
7
+ store.has('version')
8
+ )
9
+ }
10
+
11
+ const validateRequiredScanParams = params => {
12
+ return (
13
+ params.apiKey &&
14
+ params.organizationId &&
15
+ params.host &&
16
+ params.authorization &&
17
+ params.version
18
+ )
19
+ }
20
+
21
+ const validateAuthParams = params => {
22
+ return !!(
23
+ params.apiKey &&
24
+ params.organizationId &&
25
+ params.host &&
26
+ params.authorization
27
+ )
28
+ }
29
+
30
+ module.exports = {
31
+ checkConfigHasRequiredValues: checkConfigHasRequiredValues,
32
+ validateAuthParams: validateAuthParams,
33
+ validateRequiredScanParams: validateRequiredScanParams
34
+ }