@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.
- package/README.md +109 -0
- package/bin/contrast.js +2 -0
- package/dist/commands/auth/auth.js +61 -0
- package/dist/commands/config/config.js +24 -0
- package/dist/commands/scan/processScan.js +23 -0
- package/dist/common/HTTPClient.js +192 -0
- package/dist/common/errorHandling.js +60 -0
- package/dist/constants/constants.js +30 -0
- package/dist/constants/lambda.js +31 -0
- package/dist/constants/locales.js +259 -0
- package/dist/constants.js +150 -0
- package/dist/index.js +56 -0
- package/dist/lambda/__mocks__/aws.js +21 -0
- package/dist/lambda/__mocks__/lambdaConfig.json +42 -0
- package/dist/lambda/arn.js +21 -0
- package/dist/lambda/aws.js +169 -0
- package/dist/lambda/cliError.js +76 -0
- package/dist/lambda/constants.js +11 -0
- package/dist/lambda/help.js +75 -0
- package/dist/lambda/lambda.js +130 -0
- package/dist/lambda/logUtils.js +36 -0
- package/dist/lambda/scanDetail.js +30 -0
- package/dist/lambda/scanDetailCompletion.js +56 -0
- package/dist/lambda/scanRequest.js +93 -0
- package/dist/lambda/scanResults.js +16 -0
- package/dist/lambda/utils.js +90 -0
- package/dist/scan/autoDetection.js +76 -0
- package/dist/scan/fileFinder.js +15 -0
- package/dist/scan/fileUtils.js +31 -0
- package/dist/scan/help.js +68 -0
- package/dist/scan/populateProjectIdAndProjectName.js +55 -0
- package/dist/scan/scan.js +96 -0
- package/dist/scan/scanController.js +54 -0
- package/dist/scan/scanResults.js +85 -0
- package/dist/utils/commonApi.js +45 -0
- package/dist/utils/filterProjectPath.js +20 -0
- package/dist/utils/getConfig.js +30 -0
- package/dist/utils/oraWrapper.js +20 -0
- package/dist/utils/paramsUtil/commandlineParams.js +31 -0
- package/dist/utils/paramsUtil/configStoreParams.js +18 -0
- package/dist/utils/paramsUtil/envVariableParams.js +10 -0
- package/dist/utils/paramsUtil/paramHandler.js +28 -0
- package/dist/utils/paramsUtil/yamlParams.js +6 -0
- package/dist/utils/parsedCLIOptions.js +13 -0
- package/dist/utils/requestUtils.js +18 -0
- package/dist/utils/validationCheck.js +26 -0
- package/package.json +123 -0
- package/src/commands/auth/auth.js +73 -0
- package/src/commands/config/config.js +25 -0
- package/src/commands/scan/processScan.js +29 -0
- package/src/common/HTTPClient.js +269 -0
- package/src/common/errorHandling.ts +79 -0
- package/src/constants/constants.js +34 -0
- package/src/constants/lambda.js +41 -0
- package/src/constants/locales.js +381 -0
- package/src/constants.js +168 -0
- package/src/index.ts +69 -0
- package/src/lambda/__mocks__/aws.ts +32 -0
- package/src/lambda/__mocks__/lambdaConfig.json +42 -0
- package/src/lambda/arn.ts +32 -0
- package/src/lambda/aws.ts +247 -0
- package/src/lambda/cliError.ts +72 -0
- package/src/lambda/constants.ts +11 -0
- package/src/lambda/help.ts +76 -0
- package/src/lambda/lambda.ts +174 -0
- package/src/lambda/logUtils.ts +46 -0
- package/src/lambda/scanDetailCompletion.ts +78 -0
- package/src/lambda/scanRequest.ts +142 -0
- package/src/lambda/scanResults.ts +29 -0
- package/src/lambda/utils.ts +125 -0
- package/src/scan/autoDetection.js +77 -0
- package/src/scan/fileUtils.js +33 -0
- package/src/scan/help.js +74 -0
- package/src/scan/populateProjectIdAndProjectName.js +62 -0
- package/src/scan/scan.js +126 -0
- package/src/scan/scanController.js +69 -0
- package/src/scan/scanResults.js +96 -0
- package/src/utils/commonApi.js +54 -0
- package/src/utils/filterProjectPath.js +21 -0
- package/src/utils/getConfig.ts +42 -0
- package/src/utils/oraWrapper.js +24 -0
- package/src/utils/paramsUtil/commandlineParams.js +37 -0
- package/src/utils/paramsUtil/configStoreParams.js +19 -0
- package/src/utils/paramsUtil/envVariableParams.js +10 -0
- package/src/utils/paramsUtil/paramHandler.js +28 -0
- package/src/utils/parsedCLIOptions.js +17 -0
- package/src/utils/requestUtils.js +22 -0
- package/src/utils/validationCheck.js +34 -0
package/src/scan/scan.js
ADDED
|
@@ -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
|
+
}
|