@corellium/corellium-cli 1.0.4 → 1.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (247) hide show
  1. package/README.md +1 -1
  2. package/docs/OVERVIEW.md +1 -1
  3. package/node_modules/@babel/cli/node_modules/commander/package.json +58 -27
  4. package/node_modules/@babel/cli/node_modules/make-dir/package.json +93 -62
  5. package/node_modules/@babel/cli/node_modules/pify/package.json +85 -54
  6. package/node_modules/@babel/cli/node_modules/semver/package.json +51 -20
  7. package/node_modules/@babel/cli/node_modules/slash/package.json +68 -37
  8. package/node_modules/@babel/cli/package.json +69 -37
  9. package/node_modules/@corellium/client-api/package.json +40 -15
  10. package/node_modules/@jridgewell/resolve-uri/package.json +75 -40
  11. package/node_modules/@jridgewell/sourcemap-codec/package.json +74 -43
  12. package/node_modules/@jridgewell/trace-mapping/package.json +72 -40
  13. package/node_modules/@mapbox/node-pre-gyp/package.json +61 -27
  14. package/node_modules/@nicolo-ribaudo/chokidar-2/package.json +55 -22
  15. package/node_modules/abbrev/package.json +52 -18
  16. package/node_modules/agent-base/package.json +62 -33
  17. package/node_modules/ansi-regex/package.json +89 -58
  18. package/node_modules/ansi-styles/package.json +95 -59
  19. package/node_modules/anymatch/package.json +56 -28
  20. package/node_modules/aproba/package.json +50 -23
  21. package/node_modules/are-we-there-yet/node_modules/readable-stream/package.json +60 -32
  22. package/node_modules/are-we-there-yet/package.json +62 -32
  23. package/node_modules/ascii-art/package.json +83 -51
  24. package/node_modules/ascii-art-ansi/package.json +61 -30
  25. package/node_modules/ascii-art-braille/package.json +32 -7
  26. package/node_modules/ascii-art-font/package.json +47 -17
  27. package/node_modules/ascii-art-graph/package.json +34 -10
  28. package/node_modules/ascii-art-image/node_modules/ascii-art-braille/package.json +32 -7
  29. package/node_modules/ascii-art-image/package.json +36 -11
  30. package/node_modules/ascii-art-table/package.json +35 -10
  31. package/node_modules/ascii-art-utf/package.json +47 -18
  32. package/node_modules/async/package.json +55 -29
  33. package/node_modules/async-arrays/package.json +62 -34
  34. package/node_modules/asynckit/package.json +74 -45
  35. package/node_modules/axios/package.json +72 -46
  36. package/node_modules/balanced-match/package.json +49 -22
  37. package/node_modules/binary-extensions/package.json +73 -41
  38. package/node_modules/brace-expansion/package.json +50 -23
  39. package/node_modules/braces/package.json +76 -30
  40. package/node_modules/call-bind/package.json +125 -83
  41. package/node_modules/canvas/package.json +86 -43
  42. package/node_modules/chokidar/package.json +74 -40
  43. package/node_modules/chownr/package.json +56 -24
  44. package/node_modules/cli/package.json +70 -23
  45. package/node_modules/cliui/package.json +87 -53
  46. package/node_modules/color/node_modules/color-convert/package.json +60 -26
  47. package/node_modules/color/node_modules/color-name/package.json +45 -18
  48. package/node_modules/color/package.json +57 -26
  49. package/node_modules/color-convert/package.json +59 -25
  50. package/node_modules/color-difference/package.json +52 -26
  51. package/node_modules/color-model/package.json +44 -17
  52. package/node_modules/color-name/package.json +60 -32
  53. package/node_modules/color-string/package.json +67 -26
  54. package/node_modules/color-support/package.json +60 -26
  55. package/node_modules/combined-stream/package.json +52 -19
  56. package/node_modules/component-emitter/package.json +45 -17
  57. package/node_modules/concat-map/package.json +89 -45
  58. package/node_modules/console-control-strings/package.json +55 -22
  59. package/node_modules/convert-source-map/package.json +55 -28
  60. package/node_modules/cookiejar/package.json +44 -16
  61. package/node_modules/core-util-is/package.json +51 -21
  62. package/node_modules/d3/package.json +70 -43
  63. package/node_modules/d3-array/package.json +55 -24
  64. package/node_modules/d3-axis/package.json +54 -27
  65. package/node_modules/d3-brush/package.json +60 -33
  66. package/node_modules/d3-chord/package.json +55 -28
  67. package/node_modules/d3-collection/package.json +54 -25
  68. package/node_modules/d3-color/package.json +2 -2
  69. package/node_modules/d3-contour/package.json +54 -27
  70. package/node_modules/d3-dispatch/package.json +60 -28
  71. package/node_modules/d3-drag/package.json +61 -32
  72. package/node_modules/d3-dsv/node_modules/commander/package.json +56 -25
  73. package/node_modules/d3-dsv/package.json +64 -36
  74. package/node_modules/d3-ease/package.json +56 -28
  75. package/node_modules/d3-fetch/package.json +58 -31
  76. package/node_modules/d3-force/package.json +57 -30
  77. package/node_modules/d3-format/package.json +57 -29
  78. package/node_modules/d3-geo/package.json +62 -35
  79. package/node_modules/d3-hierarchy/package.json +60 -33
  80. package/node_modules/d3-interpolate/package.json +63 -31
  81. package/node_modules/d3-path/package.json +57 -28
  82. package/node_modules/d3-polygon/package.json +55 -28
  83. package/node_modules/d3-quadtree/package.json +57 -29
  84. package/node_modules/d3-random/package.json +53 -26
  85. package/node_modules/d3-scale/package.json +56 -29
  86. package/node_modules/d3-scale-chromatic/package.json +60 -33
  87. package/node_modules/d3-selection/package.json +60 -29
  88. package/node_modules/d3-shape/package.json +59 -32
  89. package/node_modules/d3-time/package.json +57 -28
  90. package/node_modules/d3-time-format/package.json +61 -33
  91. package/node_modules/d3-timer/package.json +57 -28
  92. package/node_modules/d3-transition/package.json +64 -35
  93. package/node_modules/d3-voronoi/package.json +51 -24
  94. package/node_modules/d3-zoom/package.json +61 -34
  95. package/node_modules/debug/package.json +87 -37
  96. package/node_modules/decompress-response/package.json +84 -53
  97. package/node_modules/delayed-stream/package.json +53 -19
  98. package/node_modules/delegates/package.json +45 -11
  99. package/node_modules/detect-libc/package.json +60 -26
  100. package/node_modules/dirname-shim/package.json +60 -26
  101. package/node_modules/dotenv/package.json +64 -37
  102. package/node_modules/duplexer/package.json +49 -18
  103. package/node_modules/emoji-regex/package.json +58 -32
  104. package/node_modules/escalade/package.json +59 -28
  105. package/node_modules/extended-emitter/package.json +65 -37
  106. package/node_modules/fast-safe-stringify/package.json +73 -33
  107. package/node_modules/fill-range/package.json +72 -28
  108. package/node_modules/follow-redirects/package.json +77 -42
  109. package/node_modules/form-data/package.json +74 -42
  110. package/node_modules/formidable/package.json +52 -22
  111. package/node_modules/fs-minipass/package.json +52 -24
  112. package/node_modules/fs-readdir-recursive/package.json +50 -20
  113. package/node_modules/fs.realpath/package.json +53 -21
  114. package/node_modules/fsevents/package.json +63 -38
  115. package/node_modules/ftp-response-parser/node_modules/isarray/package.json +54 -22
  116. package/node_modules/ftp-response-parser/node_modules/readable-stream/package.json +55 -22
  117. package/node_modules/ftp-response-parser/node_modules/string_decoder/package.json +45 -17
  118. package/node_modules/ftp-response-parser/package.json +64 -23
  119. package/node_modules/function-bind/package.json +61 -28
  120. package/node_modules/gauge/package.json +52 -25
  121. package/node_modules/generate-password/package.json +54 -28
  122. package/node_modules/get-caller-file/package.json +53 -27
  123. package/node_modules/get-intrinsic/package.json +124 -91
  124. package/node_modules/glob/package.json +68 -34
  125. package/node_modules/glob-parent/package.json +70 -27
  126. package/node_modules/has/package.json +55 -26
  127. package/node_modules/has-symbols/package.json +133 -104
  128. package/node_modules/has-unicode/package.json +52 -25
  129. package/node_modules/https-proxy-agent/package.json +59 -30
  130. package/node_modules/iconv-lite/package.json +77 -48
  131. package/node_modules/inflight/package.json +48 -20
  132. package/node_modules/inherits/package.json +54 -17
  133. package/node_modules/is-binary-path/package.json +75 -43
  134. package/node_modules/is-extglob/package.json +52 -22
  135. package/node_modules/is-fullwidth-code-point/package.json +79 -45
  136. package/node_modules/is-glob/package.json +68 -26
  137. package/node_modules/is-number/package.json +65 -26
  138. package/node_modules/jsftp/node_modules/debug/package.json +67 -28
  139. package/node_modules/jsftp/package.json +59 -22
  140. package/node_modules/json2csv/node_modules/commander/package.json +56 -25
  141. package/node_modules/json2csv/package.json +64 -37
  142. package/node_modules/jsonparse/package.json +53 -18
  143. package/node_modules/lodash/package.json +61 -15
  144. package/node_modules/lodash.get/package.json +67 -16
  145. package/node_modules/lru-cache/package.json +61 -27
  146. package/node_modules/make-dir/node_modules/semver/package.json +51 -20
  147. package/node_modules/make-dir/package.json +93 -62
  148. package/node_modules/maplex/package.json +54 -22
  149. package/node_modules/methods/package.json +64 -22
  150. package/node_modules/mime/package.json +48 -20
  151. package/node_modules/mime-db/package.json +67 -25
  152. package/node_modules/mime-types/package.json +64 -20
  153. package/node_modules/mimic-response/package.json +76 -45
  154. package/node_modules/minimatch/package.json +61 -25
  155. package/node_modules/minipass/package.json +64 -30
  156. package/node_modules/minizlib/package.json +59 -27
  157. package/node_modules/mkdirp/package.json +57 -27
  158. package/node_modules/ms/package.json +58 -24
  159. package/node_modules/multi-progress/package.json +46 -20
  160. package/node_modules/nan/package.json +87 -27
  161. package/node_modules/node-fetch/package.json +104 -77
  162. package/node_modules/nopt/package.json +54 -22
  163. package/node_modules/normalize-path/package.json +63 -25
  164. package/node_modules/npmlog/package.json +55 -23
  165. package/node_modules/object-assign/package.json +51 -20
  166. package/node_modules/object-inspect/package.json +81 -53
  167. package/node_modules/once/package.json +56 -19
  168. package/node_modules/parse-listing/package.json +56 -27
  169. package/node_modules/path-is-absolute/package.json +47 -16
  170. package/node_modules/picomatch/package.json +60 -28
  171. package/node_modules/progress/package.json +65 -21
  172. package/node_modules/qs/package.json +105 -78
  173. package/node_modules/readdirp/package.json +83 -47
  174. package/node_modules/require-directory/package.json +57 -29
  175. package/node_modules/rimraf/package.json +61 -23
  176. package/node_modules/rw/package.json +46 -19
  177. package/node_modules/safe-buffer/package.json +38 -10
  178. package/node_modules/safer-buffer/package.json +43 -18
  179. package/node_modules/semver/package.json +70 -36
  180. package/node_modules/set-blocking/package.json +56 -29
  181. package/node_modules/side-channel/package.json +98 -70
  182. package/node_modules/sift/package.json +62 -30
  183. package/node_modules/signal-exit/package.json +58 -29
  184. package/node_modules/simple-concat/package.json +46 -22
  185. package/node_modules/simple-get/package.json +33 -9
  186. package/node_modules/simple-swizzle/node_modules/is-arrayish/package.json +59 -28
  187. package/node_modules/simple-swizzle/package.json +57 -23
  188. package/node_modules/strangler/package.json +67 -39
  189. package/node_modules/stream-combiner/package.json +48 -15
  190. package/node_modules/string-tools/package.json +50 -16
  191. package/node_modules/string-width/package.json +97 -59
  192. package/node_modules/string_decoder/package.json +47 -18
  193. package/node_modules/strip-ansi/package.json +94 -57
  194. package/node_modules/superagent/node_modules/form-data/package.json +74 -42
  195. package/node_modules/superagent/node_modules/readable-stream/package.json +60 -32
  196. package/node_modules/superagent/package.json +59 -13
  197. package/node_modules/tar/package.json +59 -27
  198. package/node_modules/through/package.json +50 -17
  199. package/node_modules/to-regex-range/package.json +61 -25
  200. package/node_modules/tr46/package.json +51 -24
  201. package/node_modules/unorm/package.json +75 -34
  202. package/node_modules/util-deprecate/package.json +49 -19
  203. package/node_modules/uuid/package.json +102 -74
  204. package/node_modules/webidl-conversions/package.json +53 -18
  205. package/node_modules/whatwg-url/package.json +49 -15
  206. package/node_modules/wide-align/package.json +53 -21
  207. package/node_modules/wolfy87-eventemitter/package.json +49 -25
  208. package/node_modules/wrap-ansi/package.json +97 -65
  209. package/node_modules/wrappy/package.json +50 -21
  210. package/node_modules/y18n/package.json +73 -43
  211. package/node_modules/yallist/package.json +55 -20
  212. package/node_modules/yargs/package.json +99 -72
  213. package/node_modules/yargs-parser/package.json +83 -52
  214. package/package.json +2 -1
  215. package/src/commands/Client.js +2 -2
  216. package/src/commands/agent/apps.js +2 -1
  217. package/src/commands/agent/file.js +2 -1
  218. package/src/commands/agent/ready.js +2 -1
  219. package/src/commands/extensions/delete.js +2 -1
  220. package/src/commands/extensions/list.js +2 -1
  221. package/src/commands/extensions/load.js +2 -1
  222. package/src/commands/extensions/validate.js +2 -1
  223. package/src/commands/firmware/list.js +2 -1
  224. package/src/commands/firmware/load.js +2 -1
  225. package/src/commands/images/create.js +2 -1
  226. package/src/commands/images/delete.js +2 -1
  227. package/src/commands/images/list.js +2 -1
  228. package/src/commands/instances/Instance.js +27 -0
  229. package/src/commands/instances/create.js +11 -4
  230. package/src/commands/instances/delete.js +20 -5
  231. package/src/commands/instances/index.js +2 -1
  232. package/src/commands/instances/list.js +3 -2
  233. package/src/commands/instances/start.js +2 -1
  234. package/src/commands/instances/stop.js +2 -1
  235. package/src/commands/instances/upgrade.js +90 -0
  236. package/src/commands/login.js +14 -2
  237. package/src/commands/logout.js +2 -1
  238. package/src/commands/projects/create.js +2 -1
  239. package/src/commands/projects/delete.js +2 -1
  240. package/src/commands/projects/list.js +2 -1
  241. package/src/commands/webplayer/create.js +2 -1
  242. package/src/commands/webplayer/destroy.js +2 -1
  243. package/src/commands/webplayer/list.js +2 -1
  244. package/src/commands/webplayer/login.js +2 -1
  245. package/src/error.js +14 -1
  246. package/src/utils.js +11 -4
  247. package/example/WebPlayerSample.js +0 -319
@@ -3,7 +3,8 @@ const { displayTable } = require('../../table')
3
3
  const { getApi } = require('../../utils')
4
4
 
5
5
  async function builder (yargs) {
6
- yargs.option('detailed-errors', {
6
+ yargs.option('verbose', {
7
+ alias: 'v',
7
8
  type: 'boolean',
8
9
  describe: 'Console will receive verbose error output'
9
10
  }).option('project', {
@@ -31,7 +32,7 @@ async function handler (argv) {
31
32
  }
32
33
  await displayTable(argv.format, instances, [
33
34
  'id', 'flavor', 'type', 'state', 'os'
34
- ], [{ column: 3, width: 5 }, { column: 2, width: 4 }])
35
+ ], [{ column: 3, width: 5 }, { column: 2, width: 4 }, { column: 1, width: 6 }])
35
36
  } catch (error) {
36
37
  const errorMessage = getErrorMessage(error)
37
38
  console.error(`List failed: ${errorMessage}`)
@@ -8,7 +8,8 @@ async function builder (yargs) {
8
8
  describe: 'Instance id',
9
9
  demandOption: true
10
10
  })
11
- .option('detailed-errors', {
11
+ .option('verbose', {
12
+ alias: 'v',
12
13
  type: 'boolean',
13
14
  describe: 'Console will receive verbose error output'
14
15
  })
@@ -8,7 +8,8 @@ async function builder (yargs) {
8
8
  describe: 'Instance id',
9
9
  demandOption: true
10
10
  })
11
- .option('detailed-errors', {
11
+ .option('verbose', {
12
+ alias: 'v',
12
13
  type: 'boolean',
13
14
  describe: 'Console will receive verbose error output'
14
15
  })
@@ -0,0 +1,90 @@
1
+ const log = require('../../logging')
2
+ const InstanceCLI = require('./Instance')
3
+ const { getErrorMessage } = require('../../error')
4
+ const { waitForState, waitForIntervalMilliSec } = require('../../utils')
5
+
6
+ const waitForMinutes = 15
7
+
8
+ async function builder (yargs) {
9
+ yargs
10
+ .positional('instanceId', {
11
+ type: 'string',
12
+ describe: 'Instance id',
13
+ demandOption: true
14
+ })
15
+ .positional('os', {
16
+ type: 'string',
17
+ describe: 'Operating system semantic version (example: \'16.1\' or \'16.1.4\'',
18
+ demandOption: true
19
+ })
20
+ .option('osbuild', {
21
+ type: 'string',
22
+ describe: 'Use a specific build (example: \'16H20\')',
23
+ demandOption: false
24
+ })
25
+ .option('verbose', {
26
+ alias: 'v',
27
+ type: 'boolean',
28
+ describe: 'Console will receive verbose error output',
29
+ demandOption: false
30
+ })
31
+ .option('format', {
32
+ type: 'input',
33
+ describe: 'Output format (default is table) e.g. json',
34
+ string: true,
35
+ choices: ['json', 'csv'],
36
+ demandOption: false
37
+ })
38
+ .option('wait', {
39
+ type: 'boolean',
40
+ describe: 'Wait for the instance to be ready',
41
+ demandOption: false
42
+ })
43
+ }
44
+
45
+ async function handler (argv) {
46
+ try {
47
+ const { os, osbuild } = argv
48
+ const instance = new InstanceCLI(argv)
49
+ await instance.upgrade({ os, osbuild })
50
+ if (argv.wait) {
51
+ const reporter = argv.verbose
52
+ ? (info) => {
53
+ if (argv.verbose) {
54
+ let restoreStatus = ''
55
+ if (info.restoreStatus && info.restoreStatus.stage) {
56
+ restoreStatus = ` -> ${info.restoreStatus.stage}` + (info.restoreStatus.progress ? `(${parseInt(info.restoreStatus.progress)}%)` : '')
57
+ }
58
+ const report = ` - ${info.state}${restoreStatus}`
59
+ if (lastReport !== report) {
60
+ log.info(report)
61
+ }
62
+ lastReport = report
63
+ }
64
+ }
65
+ : () => { /* nop */ }
66
+ let lastReport = ''
67
+ // First wait up to 10 seconds for the update to begin
68
+ let attempts = 10000 / waitForIntervalMilliSec
69
+ await waitForState(argv.instance, instance.info.bind(instance), 'updating', attempts)
70
+ // Then wait up to "waitForMinutes" for the instance to upgrade its OS version or error out
71
+ // Using on-prem cluster ci-1, the upgrade from iOS 16.0 to 16.1 has been taking about 8-1/2 minutes
72
+ // 180 * 5 seconds = 15 minutes
73
+ log.info(`Waiting up to ${waitForMinutes} minutes for upgrade to complete...`)
74
+ attempts = (waitForMinutes * 60 * 1000) / waitForIntervalMilliSec
75
+ await waitForState(argv.instance, instance.info.bind(instance), 'on', attempts, reporter)
76
+ }
77
+ log.info(`Successfully upgraded instance ${argv.instanceId} to ${os}`)
78
+ } catch (err) {
79
+ const errorMessage = getErrorMessage(err)
80
+ log.error(`Upgrade iOS version failed: ${errorMessage}`)
81
+ if (argv.detailedErrors) { log.error(err) }
82
+ }
83
+ }
84
+
85
+ module.exports = {
86
+ builder,
87
+ handler,
88
+ command: 'upgrade <instanceId> <os> [--osbuild <buildid>] [--wait] [--format <\'json\' | \'csv\'>] [--verbose]',
89
+ describe: 'Upgrade iOS version for instance'
90
+ }
@@ -10,9 +10,11 @@ const {
10
10
  } = require('../utils')
11
11
  const https = require('https')
12
12
  const axios = require('axios').default
13
+ const prompts = require('prompts')
13
14
 
14
15
  async function builder (yargs) {
15
- yargs.option('detailed-errors', {
16
+ yargs.option('verbose', {
17
+ alias: 'v',
16
18
  type: 'boolean',
17
19
  describe: 'Console will receive verbose error output'
18
20
  }).option('endpoint', {
@@ -44,7 +46,17 @@ async function builder (yargs) {
44
46
  }
45
47
 
46
48
  async function handler (argv) {
47
- const { username, password, apitoken, endpoint } = argv
49
+ const { username, apitoken, endpoint } = argv
50
+ let { password } = argv
51
+
52
+ if (username && !password) {
53
+ password = (await prompts({
54
+ message: 'Enter your password',
55
+ name: 'password',
56
+ type: 'text',
57
+ style: 'invisible'
58
+ })).password
59
+ }
48
60
 
49
61
  // We need a special agent just for login because we can't assume profile has been written yet
50
62
  const CACert = await getCACert({ endpoint })
@@ -2,7 +2,8 @@ const asciiArt = require('ascii-art')
2
2
  const { deleteProfile } = require('../profile')
3
3
 
4
4
  async function builder (yargs) {
5
- yargs.option('detailed-errors', {
5
+ yargs.option('verbose', {
6
+ alias: 'v',
6
7
  type: 'boolean',
7
8
  describe: 'Console will receive verbose error output'
8
9
  })
@@ -3,7 +3,8 @@ const { displayTable } = require('../../table')
3
3
  const { getAxios } = require('../../utils')
4
4
 
5
5
  async function builder (yargs) {
6
- yargs.option('detailed-errors', {
6
+ yargs.option('verbose', {
7
+ alias: 'v',
7
8
  type: 'boolean',
8
9
  describe: 'Console will receive verbose error output'
9
10
  })
@@ -7,7 +7,8 @@ async function builder (yargs) {
7
7
  type: 'string',
8
8
  describe: 'Project ID',
9
9
  demandOption: true
10
- }).option('detailed-errors', {
10
+ }).option('verbose', {
11
+ alias: 'v',
11
12
  type: 'boolean',
12
13
  describe: 'Console will receive verbose error output'
13
14
  })
@@ -3,7 +3,8 @@ const { displayTable } = require('../../table')
3
3
  const { getApi } = require('../../utils')
4
4
 
5
5
  async function builder (yargs) {
6
- yargs.option('detailed-errors', {
6
+ yargs.option('verbose', {
7
+ alias: 'v',
7
8
  type: 'boolean',
8
9
  describe: 'Console will receive verbose error output'
9
10
  }).option('format', {
@@ -5,7 +5,8 @@ const { validateNonEmpty } = require('../../utils')
5
5
  const { getErrorMessage } = require('../../error')
6
6
 
7
7
  async function builder (yargs) {
8
- yargs.option('detailed-errors', {
8
+ yargs.option('verbose', {
9
+ alias: 'v',
9
10
  type: 'boolean',
10
11
  describe: 'Console will receive verbose error output'
11
12
  }).option('project', {
@@ -4,7 +4,8 @@ const { validateNonEmpty } = require('../../utils')
4
4
  const { getErrorMessage } = require('../../error')
5
5
 
6
6
  async function builder (yargs) {
7
- yargs.option('detailed-errors', {
7
+ yargs.option('verbose', {
8
+ alias: 'v',
8
9
  type: 'boolean',
9
10
  describe: 'Console will receive verbose error output'
10
11
  }).option('project', {
@@ -5,7 +5,8 @@ const { validateNonEmpty } = require('../../utils')
5
5
  const { getErrorMessage } = require('../../error')
6
6
 
7
7
  async function builder (yargs) {
8
- yargs.option('detailed-errors', {
8
+ yargs.option('verbose', {
9
+ alias: 'v',
9
10
  type: 'boolean',
10
11
  describe: 'Console will receive verbose error output'
11
12
  }).option('project', {
@@ -4,7 +4,8 @@ const { validateNonEmpty } = require('../../utils')
4
4
  const { getErrorMessage } = require('../../error')
5
5
 
6
6
  async function builder (yargs) {
7
- yargs.option('detailed-errors', {
7
+ yargs.option('verbose', {
8
+ alias: 'v',
8
9
  type: 'boolean',
9
10
  describe: 'Console will receive verbose error output'
10
11
  }).option('project', {
package/src/error.js CHANGED
@@ -1,7 +1,20 @@
1
1
 
2
+ function getUserErrorMessage (body) {
3
+ const keys = ['errorID', 'error']
4
+ if (body && body.errorID === 'UserError') {
5
+ const err = Object.keys(body)
6
+ .filter(key => !keys.includes(key))
7
+ .reduce((obj, key) => {
8
+ obj[key] = body[key]
9
+ return obj
10
+ }, {})
11
+ return JSON.stringify(err)
12
+ }
13
+ return ''
14
+ }
2
15
  function getErrorMessage (error) {
3
16
  return (error.body && error.body.error)
4
- ? error.body.error
17
+ ? `${error.body.error} ${getUserErrorMessage(error.body)}`
5
18
  : (error.error && error.error.message)
6
19
  ? error.error.message
7
20
  : error
package/src/utils.js CHANGED
@@ -9,6 +9,8 @@ axios.defaults.headers.common['User-Agent'] = `corellium-cli v${require('../pack
9
9
  const superagent = require('superagent')
10
10
  const https = require('https')
11
11
 
12
+ const waitForIntervalMilliSec = 5000
13
+
12
14
  const planOptions = (planId) => {
13
15
  let usageBased = false
14
16
  let cores, licenseType
@@ -50,11 +52,14 @@ const sleep = (milliseconds) => {
50
52
  return new Promise((resolve) => setTimeout(resolve, milliseconds))
51
53
  }
52
54
 
53
- const waitForState = async (instanceId, fn, state, attempts = 20) => {
55
+ const waitForState = async (instanceId, fn, state, attempts = 20, reporterFn = null) => {
54
56
  const response = await fn(instanceId)
57
+ if (typeof reporterFn === 'function') {
58
+ reporterFn(response)
59
+ }
55
60
  if (response.state !== state && attempts > 0) {
56
- await sleep(5000)
57
- await waitForState(instanceId, fn, state, --attempts)
61
+ await sleep(waitForIntervalMilliSec)
62
+ await waitForState(instanceId, fn, state, --attempts, reporterFn)
58
63
  }
59
64
  }
60
65
 
@@ -143,5 +148,7 @@ module.exports = {
143
148
  getApi,
144
149
  getAxios,
145
150
  validateNonEmpty,
146
- getCACert
151
+ getCACert,
152
+ sleep,
153
+ waitForIntervalMilliSec
147
154
  }
@@ -1,319 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- const path = require('path')
4
- const asciiArt = require('ascii-art')
5
- const { exec } = require('child_process')
6
- const { promisify } = require('util')
7
- const execp = promisify(exec)
8
-
9
- require('dotenv').config()
10
-
11
- const endpoint = process.env.ENDPOINT
12
- const username = process.env.USERNAME
13
- const password = process.env.PASSWORD
14
- const project = process.env.PROJECT
15
- const flavor = process.env.FLAVOR
16
- const version = process.env.VERSION
17
- const apitoken = process.env.APIKEY // Admin's API token
18
- const expiration = 24 * 60 * 60 // 24 hours (in seconds)
19
- const maxAgentTimeout = 120 // seconds
20
- let projectId, instanceId
21
-
22
- const frontendFeatureSet = {
23
- apps: true,
24
- connect: true,
25
- console: true,
26
- coretrace: true,
27
- deviceControl: true,
28
- deviceDelete: true,
29
- files: true,
30
- frida: true,
31
- images: true,
32
- messaging: true,
33
- netmon: true,
34
- network: true,
35
- portForwarding: true,
36
- powerManagement: true,
37
- profile: true,
38
- sensors: true,
39
- settings: true,
40
- snapshots: true,
41
- strace: true,
42
- system: true
43
- }
44
- const features = JSON.stringify(JSON.stringify(frontendFeatureSet))
45
-
46
- const execOptions = { cwd: path.join(__dirname, '../.') }
47
-
48
- const now = () => new Date().getTime()
49
-
50
- const sleep = (milliseconds) => {
51
- return new Promise((resolve) => setTimeout(resolve, milliseconds))
52
- }
53
-
54
- /**
55
- * Return a timestamp as delta T formatted -> mm:ss.msec
56
- * @return {string}
57
- */
58
- const INFO_COLOR = 'green'
59
- const CMD_COLOR = 'magenta'
60
- const ERROR_COLOR = 'red'
61
- const TIMESTAMP_COLOR = 'cyan'
62
- const startTime = now()
63
- const ts = () => asciiArt.style(new Date((now() - startTime)).toISOString().slice(14, 23) + ':', TIMESTAMP_COLOR, true)
64
- /**
65
- * Logging with timestamp
66
- * @param args
67
- */
68
- const logInfo = (...args) => {
69
- args.unshift(ts())
70
- console.log.bind(console, ...args)()
71
- }
72
-
73
- const logResult = (...args) => {
74
- args.unshift(asciiArt.style('', INFO_COLOR))
75
- args.unshift(ts())
76
- args[2] = '\b' + args[2]
77
- args.push(asciiArt.style('', INFO_COLOR, true))
78
- console.log.bind(console, ...args)()
79
- }
80
-
81
- const logError = (...args) => {
82
- args.unshift(asciiArt.style('', ERROR_COLOR))
83
- args.unshift(ts())
84
- args[2] = '\b' + args[2]
85
- args.push(asciiArt.style('', ERROR_COLOR, true))
86
- console.error.bind(console, ...args)()
87
- }
88
-
89
- /**
90
- * Execute a command on the local host
91
- * @param {string} cmd
92
- * @param {object} options
93
- * @return {Promise<{stdout, stderr}>}
94
- */
95
- async function execLocal (cmd, options = { quiet: false }) {
96
- const { quiet } = options
97
- if (!quiet) { logInfo(asciiArt.style('[CorelliumCLI] ' + cmd, CMD_COLOR, true)) }
98
- let { stdout, stderr } = await execp(cmd, execOptions)
99
- stdout = stdout && stdout.trim()
100
- stderr = stderr && stderr.trim()
101
- // if (stdout && stdout.length) logResult('[execLocal] stdout.:', stdout)
102
- // if (stderr && stderr.length) logError('[execLocal] stderr.:', stderr)
103
- return { stdout, stderr }
104
- }
105
-
106
- /**
107
- * Parse command results
108
- * @param {any} data
109
- * @returns {any}
110
- */
111
- const parse = (data) => { try { return JSON.parse(data) } catch (_e) { return data } }
112
-
113
- /**
114
- * List All Web Players
115
- */
116
- const listSessions = async (sessionId) => {
117
- const session = sessionId ? ` --session ${sessionId}` : ''
118
- const { stdout: result } = await execLocal(`node index.js webplayer list --project ${projectId}${session} --format json`)
119
- const sessions = parse(result)
120
- if (Array.isArray(sessions)) {
121
- logResult('Existing WebPlayers:', sessions.map(s => s.identifier))
122
- } else {
123
- logError('[listSessions]', sessions)
124
- }
125
- }
126
-
127
- // Find project by name or identifier
128
- const findProject = async (id) => {
129
- const { stdout: result } = await execLocal('node index.js project list --format json')
130
- // logInfo(result)
131
- const projects = parse(result)
132
- if (Array.isArray(projects)) {
133
- const proj = projects.find(p => p.id === id || p.name === id)
134
- if (!proj) {
135
- throw new Error(`Could not find project ${id}`)
136
- }
137
- logResult(`Found project ${proj.id} - ${proj.name}`)
138
- return proj
139
- }
140
- }
141
-
142
- /**
143
- * @return {Promise<object | undefined>}
144
- */
145
- const createInstance = async () => {
146
- const { stdout: result } = await execLocal(`node index.js instance create ${flavor} ${version} ${projectId} --format json`)
147
- // logResult(`"${result}"`)
148
- try {
149
- const instances = parse(result)
150
- if (Array.isArray(instances)) {
151
- return instances[0]
152
- } else if (typeof instances === 'string') {
153
- return [instances]
154
- }
155
- } catch (err) {
156
- console.error(err)
157
- }
158
- }
159
-
160
- const findInstance = async (id) => {
161
- let { stdout: result } = await execLocal(`node index.js instance list --project ${projectId} --format json`)
162
- // logResult(`"${result}"`)
163
- if (result === '') { result = '[]' }
164
- const instances = parse(result)
165
- if (Array.isArray(instances)) {
166
- const inst = instances.find(i => i.id === id || i.name === id || i.flavor === id)
167
- if (inst) {
168
- logInfo(`Found instance ${instanceId} - ${inst.name || inst.flavor} - State: ${inst.state}`)
169
- return inst
170
- }
171
- }
172
- }
173
-
174
- const startInstance = async () => {
175
- logInfo(`startInstance: ${instanceId}`)
176
- let { stdout: result } = await execLocal(`node index.js instance list --project ${projectId} --format json`)
177
- // logResult(`"${result}"`)
178
- const inst = await findInstance(instanceId)
179
- if (inst) {
180
- if (inst.state === 'on') {
181
- logInfo(`${inst.name || inst.flavor} is ON`)
182
- } else {
183
- logInfo(`${inst.name || inst.flavor} is OFF. Turning on ${inst.name || inst.flavor}...`);
184
- ({ stdout: result } = await execLocal(`node index.js instance start ${instanceId}`))
185
- logInfo(result)
186
- }
187
- }
188
- }
189
-
190
- const _stopInstance = async () => {
191
- logInfo(`stopInstance: ${instanceId}`)
192
- let { stdout: result } = await execLocal(`node index.js instance list --project ${projectId} --format json`)
193
- // logResult(`"${result}"`)
194
- const inst = await findInstance(instanceId)
195
- if (inst) {
196
- if (inst.state === 'on') {
197
- logInfo(`${inst.name || inst.flavor} is ON. Turning off ${inst.name || inst.flavor}...`);
198
- ({ stdout: result } = await execLocal(`node index.js instance stop ${instanceId}`))
199
- logInfo(result)
200
- } else {
201
- logInfo(`${inst.name || inst.flavor} is already OFF.`)
202
- }
203
- }
204
- }
205
-
206
- const waitForAgentReady = async (timeout) => {
207
- logInfo(`Waiting up to ${timeout / 1000} seconds for an agent to become available...`)
208
- const options = { quiet: false } // Used to toggle verbosity so we only show one polling command
209
- const startTime = now()
210
- const timeoutTime = startTime + timeout
211
- let agentObtained
212
- let dots = '\r'
213
- do {
214
- let { stdout: result } = await execLocal(`node index.js agent ready --project ${projectId} --instance ${instanceId}`, options)
215
- // logResult(`"${result}"`)
216
- options.quiet = true
217
- dots = dots + '.'
218
- process.stdout.write(dots)
219
- if (typeof result !== 'string' || result.length === 0) { result = '{"ready": false}' }
220
- try {
221
- const status = parse(result)
222
- agentObtained = status.ready
223
- // eslint-disable-next-line no-empty
224
- } catch (_err) {}
225
- if (!agentObtained) await sleep(2000)
226
- } while (!agentObtained && (now() < timeoutTime))
227
- if (now() >= timeoutTime) {
228
- throw new Error(`Timed out waiting for agent to become available on instance ${instanceId}`)
229
- }
230
- process.stdout.write('\r')
231
- logResult(`Agent available after ${Math.trunc((now() - startTime) / 1000)} seconds`)
232
- }
233
-
234
- // Log in as administrator
235
- const adminLogin = async () => {
236
- let cmd
237
- if (apitoken) {
238
- cmd = `node index.js login --endpoint ${endpoint} --apitoken ${apitoken}`
239
- } else {
240
- cmd = `node index.js login --endpoint ${endpoint} --username ${username} --password ${password}`
241
- }
242
- const { stdout: result } = await execLocal(cmd)
243
- logResult(result)
244
- }
245
-
246
- /**
247
- * Main script
248
- */
249
- (async () => {
250
- await adminLogin()
251
-
252
- // Locate project
253
- const p = await findProject(project)
254
- if (p) projectId = p.id
255
- if (!projectId) throw new Error('Missing projectId')
256
-
257
- // Locate project
258
- const i = await findInstance(flavor)
259
- instanceId = i ? i.id : (await createInstance())[0]
260
- if (!instanceId) throw new Error('Unable to get an instance')
261
-
262
- // Show existing sessions
263
- logInfo('Show all sessions')
264
- await listSessions()
265
-
266
- // Create a Web Player session and extract the new session ID
267
- let { stdout: result } = await execLocal(`node index.js webplayer create --project ${projectId} --instance ${instanceId} --features ${features} --expiresIn ${expiration}`)
268
- const parsed = parse(result)
269
- if (!Array.isArray(parsed)) { throw new Error('Web Player creation failed') }
270
- const { identifier: sessionId } = parsed[0]
271
- logResult(`Created Web Player Session ${sessionId}`)
272
-
273
- logInfo('Show all sessions')
274
- await listSessions()
275
-
276
- // Verify listing a single session
277
- logInfo('Show newly created session only')
278
- await listSessions(sessionId);
279
-
280
- // Log into the Web Player session
281
- ({ stdout: result } = await execLocal(`node index.js webplayer login --project ${projectId} --session ${sessionId}`))
282
- logResult(result)
283
-
284
- // Device must be ON before using agent
285
- await startInstance()
286
-
287
- try {
288
- // Wait for an agent to become available
289
- await waitForAgentReady(maxAgentTimeout * 1000);
290
-
291
- // List files
292
- ({ stdout: result } = await execLocal(`node index.js agent files --project ${projectId} --instance ${instanceId}`))
293
- logResult('\n', result);
294
-
295
- // List apps
296
- ({ stdout: result } = await execLocal(`node index.js agent apps --project ${projectId} --instance ${instanceId}`))
297
- logResult('\n', result)
298
- } catch (err) {
299
- logError(err)
300
- }
301
-
302
- // Turn off instance
303
- // await stopInstance()
304
-
305
- // Re-login in as administrator since the session has been destroyed
306
- await adminLogin()
307
-
308
- // Destroy the Web Player session
309
- // ({ stdout: result } = await execLocal(`node index.js webplayer destroy --project ${projectId} --session ${sessionId}`))
310
- // logResult(result)
311
-
312
- await listSessions()
313
- })()
314
- .then(() => {
315
- logInfo('-=DONE=-\n\n')
316
- })
317
- .catch(err => {
318
- logError(err)
319
- })