@contrast/contrast 1.0.0 → 1.0.1

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 (201) hide show
  1. package/.prettierignore +2 -0
  2. package/README.md +120 -47
  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 +70 -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/auth/auth.js +1 -1
  71. package/dist/commands/scan/processScan.js +19 -5
  72. package/dist/common/HTTPClient.js +101 -13
  73. package/dist/common/errorHandling.js +49 -1
  74. package/dist/common/findLatestCLIVersion.js +23 -0
  75. package/dist/constants/constants.js +1 -1
  76. package/dist/constants/lambda.js +32 -4
  77. package/dist/constants/locales.js +39 -16
  78. package/dist/constants.js +148 -20
  79. package/dist/index.js +7 -1
  80. package/dist/lambda/aws.js +14 -11
  81. package/dist/lambda/help.js +4 -0
  82. package/dist/lambda/lambda.js +50 -27
  83. package/dist/lambda/lambdaUtils.js +72 -0
  84. package/dist/lambda/logUtils.js +11 -1
  85. package/dist/lambda/scanDetailCompletion.js +4 -4
  86. package/dist/lambda/scanRequest.js +11 -5
  87. package/dist/lambda/utils.js +110 -53
  88. package/dist/scan/autoDetection.js +0 -32
  89. package/dist/scan/fileUtils.js +1 -1
  90. package/dist/scan/help.js +12 -40
  91. package/dist/scan/populateProjectIdAndProjectName.js +4 -0
  92. package/dist/scan/saveResults.js +15 -0
  93. package/dist/scan/scan.js +77 -42
  94. package/dist/scan/scanConfig.js +20 -0
  95. package/dist/scan/scanController.js +13 -15
  96. package/dist/scan/scanResults.js +18 -16
  97. package/dist/utils/commonApi.js +3 -3
  98. package/dist/utils/fileUtils.js +31 -0
  99. package/dist/utils/paramsUtil/commandlineParams.js +1 -20
  100. package/dist/utils/paramsUtil/genericCommandLineParams.js +12 -0
  101. package/dist/utils/paramsUtil/paramHandler.js +3 -6
  102. package/dist/utils/parsedCLIOptions.js +14 -8
  103. package/package.json +26 -21
  104. package/src/audit/AnalysisEngine.js +103 -0
  105. package/src/audit/catalogueApplication/catalogueApplication.js +42 -0
  106. package/src/audit/dotnetAnalysisEngine/index.js +26 -0
  107. package/src/audit/dotnetAnalysisEngine/parseLockFileContents.js +47 -0
  108. package/src/audit/dotnetAnalysisEngine/parseProjectFileContents.js +29 -0
  109. package/src/audit/dotnetAnalysisEngine/readLockFileContents.js +30 -0
  110. package/src/audit/dotnetAnalysisEngine/readProjectFileContents.js +26 -0
  111. package/src/audit/dotnetAnalysisEngine/sanitizer.js +11 -0
  112. package/src/audit/goAnalysisEngine/index.js +18 -0
  113. package/src/audit/goAnalysisEngine/parseProjectFileContents.js +209 -0
  114. package/src/audit/goAnalysisEngine/readProjectFileContents.js +31 -0
  115. package/src/audit/goAnalysisEngine/sanitizer.js +7 -0
  116. package/src/audit/javaAnalysisEngine/index.js +41 -0
  117. package/src/audit/javaAnalysisEngine/parseMavenProjectFileContents.js +222 -0
  118. package/src/audit/javaAnalysisEngine/parseProjectFileContents.js +420 -0
  119. package/src/audit/javaAnalysisEngine/readProjectFileContents.js +141 -0
  120. package/src/audit/javaAnalysisEngine/sanitizer.js +6 -0
  121. package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +35 -0
  122. package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +41 -0
  123. package/src/audit/languageAnalysisEngine/checkIdentifiedLanguageHasLockFile.js +54 -0
  124. package/src/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +32 -0
  125. package/src/audit/languageAnalysisEngine/commonApi.js +20 -0
  126. package/src/audit/languageAnalysisEngine/constants.js +23 -0
  127. package/src/audit/languageAnalysisEngine/filterProjectPath.js +21 -0
  128. package/src/audit/languageAnalysisEngine/getIdentifiedLanguageInfo.js +41 -0
  129. package/src/audit/languageAnalysisEngine/getProjectRootFilenames.js +72 -0
  130. package/src/audit/languageAnalysisEngine/index.js +45 -0
  131. package/src/audit/languageAnalysisEngine/langugageAnalysisFactory.js +94 -0
  132. package/src/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +177 -0
  133. package/src/audit/languageAnalysisEngine/report/checkIgnoreDevDep.js +27 -0
  134. package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.js +303 -0
  135. package/src/audit/languageAnalysisEngine/report/newReportingFeature.js +124 -0
  136. package/src/audit/languageAnalysisEngine/report/reportingFeature.js +190 -0
  137. package/src/audit/languageAnalysisEngine/sendSnapshot.js +51 -0
  138. package/src/audit/languageAnalysisEngine/util/capabilities.js +12 -0
  139. package/src/audit/languageAnalysisEngine/util/generalAPI.js +43 -0
  140. package/src/audit/languageAnalysisEngine/util/requestUtils.js +17 -0
  141. package/src/audit/nodeAnalysisEngine/handleNPMLockFileV2.js +49 -0
  142. package/src/audit/nodeAnalysisEngine/index.js +35 -0
  143. package/src/audit/nodeAnalysisEngine/parseNPMLockFileContents.js +20 -0
  144. package/src/audit/nodeAnalysisEngine/parseYarn2LockFileContents.js +63 -0
  145. package/src/audit/nodeAnalysisEngine/parseYarnLockFileContents.js +26 -0
  146. package/src/audit/nodeAnalysisEngine/readNPMLockFileContents.js +23 -0
  147. package/src/audit/nodeAnalysisEngine/readProjectFileContents.js +27 -0
  148. package/src/audit/nodeAnalysisEngine/readYarnLockFileContents.js +36 -0
  149. package/src/audit/nodeAnalysisEngine/sanitizer.js +11 -0
  150. package/src/audit/phpAnalysisEngine/index.js +27 -0
  151. package/src/audit/phpAnalysisEngine/parseLockFileContents.js +60 -0
  152. package/src/audit/phpAnalysisEngine/readLockFileContents.js +14 -0
  153. package/src/audit/phpAnalysisEngine/readProjectFileContents.js +25 -0
  154. package/src/audit/phpAnalysisEngine/sanitizer.js +4 -0
  155. package/src/audit/pythonAnalysisEngine/index.js +55 -0
  156. package/src/audit/pythonAnalysisEngine/parsePipfileLockContents.js +23 -0
  157. package/src/audit/pythonAnalysisEngine/parseProjectFileContents.js +33 -0
  158. package/src/audit/pythonAnalysisEngine/readPipfileLockFileContents.js +16 -0
  159. package/src/audit/pythonAnalysisEngine/readPythonProjectFileContents.js +22 -0
  160. package/src/audit/pythonAnalysisEngine/sanitizer.js +9 -0
  161. package/src/audit/rubyAnalysisEngine/index.js +30 -0
  162. package/src/audit/rubyAnalysisEngine/parseGemfileLockContents.js +215 -0
  163. package/src/audit/rubyAnalysisEngine/parsedGemfile.js +39 -0
  164. package/src/audit/rubyAnalysisEngine/readGemfileContents.js +18 -0
  165. package/src/audit/rubyAnalysisEngine/readGemfileLockContents.js +17 -0
  166. package/src/audit/rubyAnalysisEngine/sanitizer.js +8 -0
  167. package/src/commands/audit/auditConfig.ts +30 -0
  168. package/src/commands/audit/auditController.ts +31 -0
  169. package/src/commands/audit/help.ts +48 -0
  170. package/src/commands/audit/processAudit.ts +19 -0
  171. package/src/commands/auth/auth.js +1 -1
  172. package/src/commands/scan/processScan.js +20 -5
  173. package/src/common/HTTPClient.js +136 -14
  174. package/src/common/errorHandling.ts +56 -1
  175. package/src/common/findLatestCLIVersion.ts +27 -0
  176. package/src/constants/constants.js +1 -1
  177. package/src/constants/lambda.js +45 -4
  178. package/src/constants/locales.js +48 -20
  179. package/src/constants.js +168 -22
  180. package/src/index.ts +9 -2
  181. package/src/lambda/aws.ts +13 -12
  182. package/src/lambda/help.ts +4 -0
  183. package/src/lambda/lambda.ts +53 -34
  184. package/src/lambda/lambdaUtils.ts +111 -0
  185. package/src/lambda/logUtils.ts +19 -1
  186. package/src/lambda/scanDetailCompletion.ts +4 -4
  187. package/src/lambda/scanRequest.ts +13 -11
  188. package/src/lambda/utils.ts +149 -81
  189. package/src/scan/autoDetection.js +0 -29
  190. package/src/scan/fileUtils.js +1 -1
  191. package/src/scan/help.js +12 -45
  192. package/src/scan/populateProjectIdAndProjectName.js +4 -0
  193. package/src/scan/saveResults.js +15 -0
  194. package/src/scan/scan.js +95 -59
  195. package/src/scan/scanConfig.js +29 -0
  196. package/src/scan/scanController.js +13 -13
  197. package/src/scan/scanResults.js +21 -19
  198. package/src/utils/commonApi.js +2 -3
  199. package/src/utils/paramsUtil/commandlineParams.js +1 -26
  200. package/src/utils/paramsUtil/paramHandler.js +3 -7
  201. package/src/utils/parsedCLIOptions.js +11 -9
package/src/constants.js CHANGED
@@ -27,7 +27,7 @@ const scanOptionDefinitions = [
27
27
  '{bold ' +
28
28
  i18n.__('constantsOptional') +
29
29
  '}: ' +
30
- i18n.__('constantsFileName')
30
+ i18n.__('scanOptionsFileNameSummary')
31
31
  },
32
32
  {
33
33
  name: 'project-id',
@@ -46,16 +46,7 @@ const scanOptionDefinitions = [
46
46
  '{bold ' +
47
47
  i18n.__('constantsOptional') +
48
48
  '}: ' +
49
- i18n.__('constantsScanTimeout')
50
- },
51
- {
52
- name: 'language',
53
- alias: 'l',
54
- description:
55
- '{bold ' +
56
- i18n.__('constantsRequiredCatalogue') +
57
- '}: ' +
58
- i18n.__('constantsLanguage')
49
+ i18n.__('scanOptionsTimeoutSummary')
59
50
  },
60
51
  {
61
52
  name: 'organization-id',
@@ -66,15 +57,6 @@ const scanOptionDefinitions = [
66
57
  '}: ' +
67
58
  i18n.__('constantsOrganizationId')
68
59
  },
69
- {
70
- name: 'yaml-path',
71
- alias: 'y',
72
- description:
73
- '{bold ' +
74
- i18n.__('constantsOptional') +
75
- '}: ' +
76
- i18n.__('constantsYamlPath')
77
- },
78
60
  {
79
61
  name: 'api-key',
80
62
  description:
@@ -94,7 +76,6 @@ const scanOptionDefinitions = [
94
76
  {
95
77
  name: 'host',
96
78
  alias: 'h',
97
- defaultValue: 'app.contrastsecurity.com',
98
79
  description:
99
80
  '{bold ' +
100
81
  i18n.__('constantsRequired') +
@@ -127,9 +108,173 @@ const scanOptionDefinitions = [
127
108
  '}:' +
128
109
  i18n.__('constantsIgnoreCertErrors')
129
110
  },
111
+ {
112
+ name: 'verbose',
113
+ alias: 'v',
114
+ type: Boolean,
115
+ description:
116
+ '{bold ' +
117
+ i18n.__('constantsOptional') +
118
+ '}:' +
119
+ i18n.__('scanOptionsVerboseSummary')
120
+ },
121
+ {
122
+ name: 'save',
123
+ alias: 's',
124
+ description:
125
+ '{bold ' + i18n.__('constantsOptional') + '}:' + i18n.__('constantsSave')
126
+ },
130
127
  {
131
128
  name: 'help',
132
129
  type: Boolean
130
+ },
131
+ {
132
+ name: 'debug',
133
+ alias: 'd',
134
+ type: Boolean
135
+ }
136
+ ]
137
+
138
+ const auditOptionDefinitions = [
139
+ {
140
+ name: 'application-id',
141
+ description:
142
+ '{bold ' +
143
+ i18n.__('constantsRequired') +
144
+ '}: ' +
145
+ i18n.__('constantsApplicationId')
146
+ },
147
+ {
148
+ name: 'application-name',
149
+ description:
150
+ '{bold ' +
151
+ i18n.__('constantsOptional') +
152
+ '}: ' +
153
+ i18n.__('constantsApplicationName')
154
+ },
155
+ {
156
+ name: 'project-path',
157
+ defaultValue: process.env.PWD,
158
+ description:
159
+ '{bold ' +
160
+ i18n.__('constantsOptional') +
161
+ '}: ' +
162
+ i18n.__('constantsProjectPath')
163
+ },
164
+ {
165
+ name: 'app-groups',
166
+ description:
167
+ '{bold ' +
168
+ i18n.__('constantsOptionalForCatalogue') +
169
+ '}: ' +
170
+ i18n.__('constantsAppGroups')
171
+ },
172
+ {
173
+ name: 'sub-project',
174
+ description:
175
+ '{bold ' +
176
+ i18n.__('constantsOptional') +
177
+ '}: ' +
178
+ i18n.__('constantsGradleMultiProject')
179
+ },
180
+ {
181
+ name: 'metadata',
182
+ description:
183
+ '{bold ' +
184
+ i18n.__('constantsOptional') +
185
+ '}: ' +
186
+ i18n.__('constantsMetadata')
187
+ },
188
+ {
189
+ name: 'tags',
190
+ description:
191
+ '{bold ' + i18n.__('constantsOptional') + '}: ' + i18n.__('constantsTags')
192
+ },
193
+ {
194
+ name: 'code',
195
+ description:
196
+ '{bold ' + i18n.__('constantsOptional') + '}: ' + i18n.__('constantsCode')
197
+ },
198
+ {
199
+ name: 'ignore-dev',
200
+ type: Boolean,
201
+ description:
202
+ '{bold ' +
203
+ i18n.__('constantsOptional') +
204
+ '}: ' +
205
+ i18n.__('constantsIgnoreDev')
206
+ },
207
+ {
208
+ name: 'maven-settings-path'
209
+ },
210
+ {
211
+ name: 'language',
212
+ alias: 'l',
213
+ description:
214
+ '{bold ' +
215
+ i18n.__('constantsRequiredCatalogue') +
216
+ '}: ' +
217
+ i18n.__('constantsLanguage')
218
+ },
219
+ {
220
+ name: 'organization-id',
221
+ alias: 'o',
222
+ description:
223
+ '{bold ' +
224
+ i18n.__('constantsRequired') +
225
+ '}: ' +
226
+ i18n.__('constantsOrganizationId')
227
+ },
228
+ {
229
+ name: 'api-key',
230
+ description:
231
+ '{bold ' +
232
+ i18n.__('constantsRequired') +
233
+ '}: ' +
234
+ i18n.__('constantsApiKey')
235
+ },
236
+ {
237
+ name: 'authorization',
238
+ description:
239
+ '{bold ' +
240
+ i18n.__('constantsRequired') +
241
+ '}: ' +
242
+ i18n.__('constantsAuthorization')
243
+ },
244
+ {
245
+ name: 'host',
246
+ alias: 'h',
247
+ description:
248
+ '{bold ' +
249
+ i18n.__('constantsRequired') +
250
+ '}: ' +
251
+ i18n.__('constantsHostId')
252
+ },
253
+ {
254
+ name: 'proxy',
255
+ description:
256
+ '{bold ' +
257
+ i18n.__('constantsOptional') +
258
+ '}: ' +
259
+ i18n.__('constantsProxyServer')
260
+ },
261
+ {
262
+ name: 'ignore-cert-errors',
263
+ type: Boolean,
264
+ description:
265
+ '{bold ' +
266
+ i18n.__('constantsOptional') +
267
+ '}:' +
268
+ i18n.__('constantsIgnoreCertErrors')
269
+ },
270
+ {
271
+ name: 'save',
272
+ alias: 's',
273
+ description:
274
+ '{bold ' +
275
+ i18n.__('constantsOptional') +
276
+ '}: ' +
277
+ i18n.__('auditOptionsSaveDescription')
133
278
  }
134
279
  ]
135
280
 
@@ -163,6 +308,7 @@ module.exports = {
163
308
  commandLineDefinitions: {
164
309
  mainUsageGuide,
165
310
  mainDefinition,
166
- scanOptionDefinitions
311
+ scanOptionDefinitions,
312
+ auditOptionDefinitions
167
313
  }
168
314
  }
package/src/index.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import commandLineArgs from 'command-line-args'
2
+ import { processAudit } from './commands/audit/processAudit'
2
3
  import { processAuth } from './commands/auth/auth'
3
4
  import { processConfig } from './commands/config/config'
4
5
  import { processScan } from './commands/scan/processScan'
@@ -6,6 +7,7 @@ import constants from './constants'
6
7
  import { APP_NAME, APP_VERSION } from './constants/constants'
7
8
  import { processLambda } from './lambda/lambda'
8
9
  import { localConfig } from './utils/getConfig'
10
+ import findLatestCLIVersion from './common/findLatestCLIVersion'
9
11
 
10
12
  const {
11
13
  commandLineDefinitions: { mainUsageGuide, mainDefinition }
@@ -36,6 +38,8 @@ const start = async () => {
36
38
  return
37
39
  }
38
40
 
41
+ await findLatestCLIVersion()
42
+
39
43
  if (command === 'config') {
40
44
  return processConfig(argvMain, config)
41
45
  }
@@ -48,9 +52,12 @@ const start = async () => {
48
52
  return await processLambda(argvMain)
49
53
  }
50
54
 
51
- /* second - parse the merge command options */
52
55
  if (command === 'scan') {
53
- return await processScan()
56
+ return await processScan(argvMain)
57
+ }
58
+
59
+ if (command === 'audit') {
60
+ return await processAudit(argvMain)
54
61
  }
55
62
 
56
63
  if (
package/src/lambda/aws.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import i18n from 'i18n'
1
2
  import {
2
3
  Lambda,
3
4
  GetFunctionCommand,
@@ -44,12 +45,9 @@ const getLambdaClient = (lambdaOptions: LambdaOptions) => {
44
45
  const clientOptions = getAwsClientOptions(lambdaOptions)
45
46
  return new Lambda(clientOptions)
46
47
  } catch (error) {
47
- const errorObj = error as any
48
- if (errorObj?.code === 'ERR_INVALID_URL') {
49
- throw new CliError(ERRORS.AWS_ERROR, { description: errorObj.message })
50
- }
51
-
52
- throw error
48
+ throw new CliError(ERRORS.AWS_ERROR, {
49
+ description: (error as Error).message
50
+ })
53
51
  }
54
52
  }
55
53
 
@@ -89,7 +87,9 @@ const getLayersLinks = async (
89
87
  }
90
88
  } catch (e) {
91
89
  if (e instanceof ResourceNotFoundException) {
92
- e.message = `The layer ${layerDict.Arn} could not be found. We will continue the scan without it.`
90
+ e.message = i18n.__('layerNotFound', {
91
+ layerArn: layerDict.Arn || 'unknown_arn'
92
+ })
93
93
  throw e
94
94
  }
95
95
  throw e
@@ -190,10 +190,10 @@ const getAttachedPolicies = async (roleName: string, client: IAMClient) => {
190
190
  )
191
191
  const attachedPoliciesPromises = listAttachedPolicies.map(
192
192
  async (policyDict: { PolicyArn: any; PolicyName: any }) => {
193
- const getPolicyCommand = new GetPolicyCommand({
194
- PolicyArn: policyDict.PolicyArn
195
- })
193
+ const { PolicyArn, PolicyName } = policyDict
194
+ const getPolicyCommand = new GetPolicyCommand({ PolicyArn })
196
195
  const policy = await client.send(getPolicyCommand)
196
+
197
197
  if (policy.Policy) {
198
198
  const getPolicyVersionCommand = new GetPolicyVersionCommand({
199
199
  PolicyArn: policy.Policy.Arn,
@@ -203,8 +203,9 @@ const getAttachedPolicies = async (roleName: string, client: IAMClient) => {
203
203
  const policyDoc = JSON.parse(
204
204
  decodeURIComponent(policyVersion?.PolicyVersion?.Document || '{}')
205
205
  )
206
- policyDoc['PolicyName'] = policyDict.PolicyName
207
- policyDoc['PolicyArn'] = policyDict.PolicyArn
206
+
207
+ policyDoc['PolicyName'] = PolicyName
208
+ policyDoc['PolicyArn'] = PolicyArn
208
209
  return policyDoc
209
210
  }
210
211
  }
@@ -21,6 +21,10 @@ const lambdaUsageGuide = commandLineUsage([
21
21
  name: i18n.__('lambdaFunctionNameOption'),
22
22
  summary: i18n.__('lambdaFunctionNameSummery')
23
23
  },
24
+ {
25
+ name: i18n.__('lambdaListFunctionsOption'),
26
+ summary: i18n.__('lambdaListFunctionsSummery')
27
+ },
24
28
  {
25
29
  name: i18n.__('lambdaEndpointOption'),
26
30
  summary:
@@ -10,10 +10,12 @@ import { log } from './logUtils'
10
10
  import { pollScanUntilCompletion } from './scanDetailCompletion'
11
11
  import { requestScanFunctionPost } from './scanRequest'
12
12
  import { getScanResults } from './scanResults'
13
- import { prettyPrintResults } from './utils'
13
+ import { printResults } from './utils'
14
+ import { getAllLambdas, printAvailableLambdas } from './lambdaUtils'
14
15
 
15
16
  type LambdaOptions = {
16
17
  functionName?: string
18
+ listFunctions?: boolean
17
19
  region?: string
18
20
  endpointUrl?: string
19
21
  profile?: string
@@ -42,38 +44,49 @@ const printHelpMessage = () => {
42
44
  }
43
45
 
44
46
  const getLambdaOptions = (argv: string[]) => {
45
- const lambdaDefinitions = [
46
- { name: 'function-name', alias: 'f', type: String },
47
- { name: 'region', alias: 'r', type: String },
48
- { name: 'endpoint-url', alias: 'e', type: String },
49
- { name: 'profile', alias: 'p', type: String },
50
- { name: 'help', alias: 'h', type: Boolean },
51
- { name: 'verbose', alias: 'v', type: Boolean },
52
- { name: 'json-output', alias: 'j', type: Boolean }
53
- ]
54
-
55
- const lambdaOptions: LambdaOptions = commandLineArgs(lambdaDefinitions, {
56
- argv,
57
- partial: true,
58
- camelCase: true,
59
- caseInsensitive: true
60
- })
61
-
62
- return lambdaOptions
47
+ try {
48
+ const lambdaDefinitions = [
49
+ { name: 'function-name', alias: 'f', type: String },
50
+ { name: 'list-functions', alias: 'l', type: Boolean },
51
+ { name: 'region', alias: 'r', type: String },
52
+ { name: 'endpoint-url', alias: 'e', type: String },
53
+ { name: 'profile', alias: 'p', type: String },
54
+ { name: 'help', alias: 'h', type: Boolean },
55
+ { name: 'verbose', alias: 'v', type: Boolean },
56
+ { name: 'json-output', alias: 'j', type: Boolean }
57
+ ]
58
+
59
+ const lambdaOptions: LambdaOptions = commandLineArgs(lambdaDefinitions, {
60
+ argv,
61
+ partial: true,
62
+ camelCase: true,
63
+ caseInsensitive: true
64
+ })
65
+
66
+ return lambdaOptions
67
+ } catch (error) {
68
+ throw new CliError(ERRORS.VALIDATION_FAILED, {
69
+ description: (error as Error).message
70
+ })
71
+ }
63
72
  }
64
73
 
65
74
  const processLambda = async (argv: string[]) => {
66
- const lambdaOptions = getLambdaOptions(argv)
67
- const { help } = lambdaOptions
75
+ try {
76
+ const lambdaOptions = getLambdaOptions(argv)
77
+ const { help } = lambdaOptions
68
78
 
69
- if (help) {
70
- return handleLambdaHelp()
71
- }
79
+ if (help) {
80
+ return handleLambdaHelp()
81
+ }
72
82
 
73
- try {
74
83
  validateRequiredLambdaParams(lambdaOptions)
75
84
 
76
- await actualProcessLambda(lambdaOptions)
85
+ if (lambdaOptions.listFunctions) {
86
+ await getAvailableFunctions(lambdaOptions)
87
+ } else {
88
+ await actualProcessLambda(lambdaOptions)
89
+ }
77
90
  } catch (error) {
78
91
  if (error instanceof CliError) {
79
92
  console.error(error.getErrorMessage())
@@ -84,6 +97,11 @@ const processLambda = async (argv: string[]) => {
84
97
  }
85
98
  }
86
99
 
100
+ const getAvailableFunctions = async (lambdaOptions: LambdaOptions) => {
101
+ const lambdas = await getAllLambdas(lambdaOptions)
102
+ printAvailableLambdas(lambdas, { runtimes: ['python', 'java'] })
103
+ }
104
+
87
105
  const actualProcessLambda = async (lambdaOptions: LambdaOptions) => {
88
106
  const auth = getAuth()
89
107
  const startTime = performance.now()
@@ -134,18 +152,20 @@ const actualProcessLambda = async (lambdaOptions: LambdaOptions) => {
134
152
  log(`----- Scan completed ${(scanDurationMs / 1000).toFixed(2)}s -----`)
135
153
 
136
154
  if (results?.length) {
137
- prettyPrintResults(results)
155
+ printResults(results)
138
156
  }
139
157
  }
140
158
 
141
159
  const validateRequiredLambdaParams = (options: LambdaOptions) => {
142
160
  if (options._unknown?.length) {
143
161
  throw new CliError(ERRORS.VALIDATION_FAILED, {
144
- description: i18n.__('notSupportedFlags', options._unknown.join('\n'))
162
+ description: i18n.__('notSupportedFlags', {
163
+ flags: options._unknown.join('\n')
164
+ })
145
165
  })
146
166
  }
147
167
 
148
- if (!options?.functionName) {
168
+ if (!options?.functionName && !options?.listFunctions) {
149
169
  throw new CliError(ERRORS.VALIDATION_FAILED, {
150
170
  errorCode: 'missingFunctionName'
151
171
  })
@@ -158,10 +178,9 @@ const validateRequiredLambdaParams = (options: LambdaOptions) => {
158
178
 
159
179
  if (flagsWithoutValues.length) {
160
180
  throw new CliError(ERRORS.VALIDATION_FAILED, {
161
- description: i18n.__(
162
- 'missingFlagArguments',
163
- flagsWithoutValues.join('\n')
164
- )
181
+ description: i18n.__('missingFlagArguments', {
182
+ flags: flagsWithoutValues.join('\n')
183
+ })
165
184
  })
166
185
  }
167
186
  }
@@ -171,4 +190,4 @@ const handleLambdaHelp = () => {
171
190
  process.exit(0)
172
191
  }
173
192
 
174
- export { processLambda, LambdaOptions, ApiParams }
193
+ export { processLambda, LambdaOptions, ApiParams, getAvailableFunctions }
@@ -0,0 +1,111 @@
1
+ import logSymbols from 'log-symbols'
2
+ import chalk from 'chalk'
3
+ import i18n from 'i18n'
4
+ import {
5
+ FunctionConfiguration,
6
+ ListFunctionsCommand
7
+ } from '@aws-sdk/client-lambda'
8
+ import { groupBy, sortBy } from 'lodash'
9
+ import { getLambdaClient } from './aws'
10
+ import ora from '../utils/oraWrapper'
11
+ import { LambdaOptions } from './lambda'
12
+ import { log, getReadableFileSize } from './logUtils'
13
+
14
+ type RuntimeLanguage = 'java' | 'python'
15
+
16
+ type FilterLambdas = {
17
+ runtimes: RuntimeLanguage[]
18
+ filterText?: string
19
+ }
20
+
21
+ /**
22
+ *
23
+ * @param fucntions all user lambdas
24
+ * @param options filter values: runtime / free text
25
+ * @returns
26
+ */
27
+ const printAvailableLambdas = (
28
+ fucntions: FunctionConfiguration[] = [],
29
+ options: FilterLambdas
30
+ ) => {
31
+ const { runtimes, filterText = '' } = options
32
+ const searchValue = filterText?.trim().toLowerCase()
33
+
34
+ const filteredFunctions = fucntions
35
+ .filter(f => runtimes.some(r => f.Runtime?.includes(r)))
36
+ .filter(f => f.FunctionName?.toLowerCase().includes(searchValue))
37
+ log(
38
+ i18n.__('availableForScan', {
39
+ icon: logSymbols.success,
40
+ count: `${filteredFunctions.length}`
41
+ })
42
+ )
43
+ const groupByRuntime = groupBy(filteredFunctions, 'Runtime')
44
+
45
+ Object.entries(groupByRuntime).forEach(([runtime, arr]) => {
46
+ const sorted = sortBy(arr, 'FunctionName')
47
+ const count = `${arr.filter(a => a.Runtime === runtime).length}`
48
+
49
+ log(chalk.gray(i18n.__('runtimeCount', { runtime, count })))
50
+ sorted.forEach(f => {
51
+ const size = f.CodeSize ? getReadableFileSize(f.CodeSize) : ''
52
+ log(`${f.FunctionName} ${chalk.gray(`(${size})`)}`)
53
+ })
54
+ })
55
+ }
56
+
57
+ /**
58
+ *
59
+ * @param lambdaOptions to create lambdaClient
60
+ * @returns list of all user lambdas that availbale to scan
61
+ */
62
+ const getAllLambdas = async (lambdaOptions: LambdaOptions) => {
63
+ const functions: FunctionConfiguration[] = []
64
+ const spinner = ora.returnOra(i18n.__('loadingFunctionList'))
65
+
66
+ try {
67
+ const client = getLambdaClient(lambdaOptions)
68
+ const command = new ListFunctionsCommand({})
69
+
70
+ ora.startSpinner(spinner)
71
+
72
+ const data = await client.send(command)
73
+ const { Functions } = data
74
+ let { NextMarker } = data
75
+
76
+ if (!Functions?.length) {
77
+ ora.failSpinner(spinner, i18n.__('noFunctionsFound'))
78
+ return
79
+ }
80
+
81
+ functions.push(...Functions)
82
+ spinner.text = i18n.__('functionsFound', { count: `${functions.length}` })
83
+
84
+ // pagination on functions
85
+ while (NextMarker) {
86
+ command.input.Marker = NextMarker
87
+ const chank = await client.send(command)
88
+
89
+ if (chank.Functions?.length) {
90
+ functions.push(...chank.Functions)
91
+ spinner.text = i18n.__('functionsFound', {
92
+ count: `${functions.length}`
93
+ })
94
+ }
95
+
96
+ NextMarker = chank.NextMarker
97
+ }
98
+
99
+ ora.succeedSpinner(
100
+ spinner,
101
+ i18n.__('functionsFound', { count: `${functions.length}` })
102
+ )
103
+ } catch (error) {
104
+ ora.failSpinner(spinner, i18n.__('failedToLoadFunctions'))
105
+ throw error
106
+ }
107
+
108
+ return functions
109
+ }
110
+
111
+ export { getAllLambdas, printAvailableLambdas }
@@ -43,4 +43,22 @@ const prettyPrintJson = (obj: string | any, depth: number | null = null) => {
43
43
  console.log(util.inspect(objToPrint, { colors: true, depth }))
44
44
  }
45
45
 
46
- export { log, prettyPrintJson }
46
+ /**
47
+ *
48
+ * @param fileSizeInBytes
49
+ *
50
+ * @returns human readable format
51
+ */
52
+ const getReadableFileSize = (fileSizeInBytes: number) => {
53
+ let i = -1
54
+ const byteUnits = [' kB', ' MB', ' GB', ' TB', 'PB', 'EB', 'ZB', 'YB']
55
+
56
+ do {
57
+ fileSizeInBytes = fileSizeInBytes / 1024
58
+ i++
59
+ } while (fileSizeInBytes > 1024)
60
+
61
+ return Math.max(fileSizeInBytes, 0.1).toFixed(1) + byteUnits[i]
62
+ }
63
+
64
+ export { log, prettyPrintJson, getReadableFileSize }
@@ -1,3 +1,4 @@
1
+ import i18n from 'i18n'
1
2
  import { sleep } from '../utils/requestUtils'
2
3
  import { getHttpClient } from '../utils/commonApi'
3
4
  import { ApiParams } from './lambda'
@@ -35,9 +36,8 @@ const pollScanUntilCompletion = async (
35
36
  const client = getHttpClient(config)
36
37
 
37
38
  const activeStatuses = ['PENDING', 'SCANNING', 'QUEUED']
38
- const startedText = 'Scan started'
39
39
  const maxEndTime = new Date().getTime() + timeoutInMinutes * MS_IN_MINUTE
40
- const startScanSpinner = ora.returnOra(startedText)
40
+ const startScanSpinner = ora.returnOra(i18n.__('scanStarted'))
41
41
  ora.startSpinner(startScanSpinner)
42
42
 
43
43
  await sleep(5000) // wait 5 sec before first polling
@@ -62,12 +62,12 @@ const pollScanUntilCompletion = async (
62
62
 
63
63
  await sleep(2 * 1000)
64
64
  } catch (error) {
65
- ora.failSpinner(startScanSpinner, 'Scan Failed')
65
+ ora.failSpinner(startScanSpinner, i18n.__('scanFailed'))
66
66
  throw error
67
67
  }
68
68
 
69
69
  if (Date.now() >= maxEndTime) {
70
- ora.failSpinner(startScanSpinner, 'Scan timed out')
70
+ ora.failSpinner(startScanSpinner, i18n.__('scanTimedOut'))
71
71
  throw new CliError(ERRORS.FAILED_TO_GET_SCAN, {
72
72
  errorCode: 'waitingTimedOut'
73
73
  })