@corellium/corellium-cli 1.0.4 → 1.0.7
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 +1 -1
- package/docs/OVERVIEW.md +1 -1
- package/index.js +2 -2
- package/node_modules/@babel/cli/node_modules/commander/package.json +58 -27
- package/node_modules/@babel/cli/node_modules/make-dir/package.json +93 -62
- package/node_modules/@babel/cli/node_modules/pify/package.json +85 -54
- package/node_modules/@babel/cli/node_modules/semver/package.json +51 -20
- package/node_modules/@babel/cli/node_modules/slash/package.json +68 -37
- package/node_modules/@babel/cli/package.json +69 -37
- package/node_modules/@corellium/client-api/package.json +40 -15
- package/node_modules/@jridgewell/resolve-uri/package.json +75 -40
- package/node_modules/@jridgewell/sourcemap-codec/package.json +74 -43
- package/node_modules/@jridgewell/trace-mapping/package.json +72 -40
- package/node_modules/@mapbox/node-pre-gyp/package.json +61 -27
- package/node_modules/@nicolo-ribaudo/chokidar-2/package.json +55 -22
- package/node_modules/abbrev/package.json +52 -18
- package/node_modules/agent-base/package.json +62 -33
- package/node_modules/ansi-regex/package.json +89 -58
- package/node_modules/ansi-styles/package.json +95 -59
- package/node_modules/anymatch/package.json +56 -28
- package/node_modules/aproba/package.json +50 -23
- package/node_modules/are-we-there-yet/node_modules/readable-stream/package.json +60 -32
- package/node_modules/are-we-there-yet/package.json +62 -32
- package/node_modules/ascii-art/package.json +83 -51
- package/node_modules/ascii-art-ansi/package.json +61 -30
- package/node_modules/ascii-art-braille/package.json +32 -7
- package/node_modules/ascii-art-font/package.json +47 -17
- package/node_modules/ascii-art-graph/package.json +34 -10
- package/node_modules/ascii-art-image/node_modules/ascii-art-braille/package.json +32 -7
- package/node_modules/ascii-art-image/package.json +36 -11
- package/node_modules/ascii-art-table/package.json +35 -10
- package/node_modules/ascii-art-utf/package.json +47 -18
- package/node_modules/async/package.json +55 -29
- package/node_modules/async-arrays/package.json +62 -34
- package/node_modules/asynckit/package.json +74 -45
- package/node_modules/axios/package.json +72 -46
- package/node_modules/balanced-match/package.json +49 -22
- package/node_modules/binary-extensions/package.json +73 -41
- package/node_modules/brace-expansion/package.json +50 -23
- package/node_modules/braces/package.json +76 -30
- package/node_modules/call-bind/package.json +125 -83
- package/node_modules/canvas/package.json +86 -43
- package/node_modules/chokidar/package.json +74 -40
- package/node_modules/chownr/package.json +56 -24
- package/node_modules/cli/package.json +70 -23
- package/node_modules/cliui/package.json +87 -53
- package/node_modules/color/node_modules/color-convert/package.json +60 -26
- package/node_modules/color/node_modules/color-name/package.json +45 -18
- package/node_modules/color/package.json +57 -26
- package/node_modules/color-convert/package.json +59 -25
- package/node_modules/color-difference/package.json +52 -26
- package/node_modules/color-model/package.json +44 -17
- package/node_modules/color-name/package.json +60 -32
- package/node_modules/color-string/package.json +67 -26
- package/node_modules/color-support/package.json +60 -26
- package/node_modules/combined-stream/package.json +52 -19
- package/node_modules/component-emitter/package.json +45 -17
- package/node_modules/concat-map/package.json +89 -45
- package/node_modules/console-control-strings/package.json +55 -22
- package/node_modules/convert-source-map/package.json +55 -28
- package/node_modules/cookiejar/package.json +44 -16
- package/node_modules/core-util-is/package.json +51 -21
- package/node_modules/d3/package.json +70 -43
- package/node_modules/d3-array/package.json +55 -24
- package/node_modules/d3-axis/package.json +54 -27
- package/node_modules/d3-brush/package.json +60 -33
- package/node_modules/d3-chord/package.json +55 -28
- package/node_modules/d3-collection/package.json +54 -25
- package/node_modules/d3-color/package.json +2 -2
- package/node_modules/d3-contour/package.json +54 -27
- package/node_modules/d3-dispatch/package.json +60 -28
- package/node_modules/d3-drag/package.json +61 -32
- package/node_modules/d3-dsv/node_modules/commander/package.json +56 -25
- package/node_modules/d3-dsv/package.json +64 -36
- package/node_modules/d3-ease/package.json +56 -28
- package/node_modules/d3-fetch/package.json +58 -31
- package/node_modules/d3-force/package.json +57 -30
- package/node_modules/d3-format/package.json +57 -29
- package/node_modules/d3-geo/package.json +62 -35
- package/node_modules/d3-hierarchy/package.json +60 -33
- package/node_modules/d3-interpolate/package.json +63 -31
- package/node_modules/d3-path/package.json +57 -28
- package/node_modules/d3-polygon/package.json +55 -28
- package/node_modules/d3-quadtree/package.json +57 -29
- package/node_modules/d3-random/package.json +53 -26
- package/node_modules/d3-scale/package.json +56 -29
- package/node_modules/d3-scale-chromatic/package.json +60 -33
- package/node_modules/d3-selection/package.json +60 -29
- package/node_modules/d3-shape/package.json +59 -32
- package/node_modules/d3-time/package.json +57 -28
- package/node_modules/d3-time-format/package.json +61 -33
- package/node_modules/d3-timer/package.json +57 -28
- package/node_modules/d3-transition/package.json +64 -35
- package/node_modules/d3-voronoi/package.json +51 -24
- package/node_modules/d3-zoom/package.json +61 -34
- package/node_modules/debug/package.json +87 -37
- package/node_modules/decompress-response/package.json +84 -53
- package/node_modules/delayed-stream/package.json +53 -19
- package/node_modules/delegates/package.json +45 -11
- package/node_modules/detect-libc/package.json +60 -26
- package/node_modules/dirname-shim/package.json +60 -26
- package/node_modules/dotenv/package.json +64 -37
- package/node_modules/duplexer/package.json +49 -18
- package/node_modules/emoji-regex/package.json +58 -32
- package/node_modules/escalade/package.json +59 -28
- package/node_modules/extended-emitter/package.json +65 -37
- package/node_modules/fast-safe-stringify/package.json +73 -33
- package/node_modules/fill-range/package.json +72 -28
- package/node_modules/follow-redirects/package.json +77 -42
- package/node_modules/form-data/package.json +74 -42
- package/node_modules/formidable/package.json +52 -22
- package/node_modules/fs-minipass/package.json +52 -24
- package/node_modules/fs-readdir-recursive/package.json +50 -20
- package/node_modules/fs.realpath/package.json +53 -21
- package/node_modules/fsevents/package.json +63 -38
- package/node_modules/ftp-response-parser/node_modules/isarray/package.json +54 -22
- package/node_modules/ftp-response-parser/node_modules/readable-stream/package.json +55 -22
- package/node_modules/ftp-response-parser/node_modules/string_decoder/package.json +45 -17
- package/node_modules/ftp-response-parser/package.json +64 -23
- package/node_modules/function-bind/package.json +61 -28
- package/node_modules/gauge/package.json +52 -25
- package/node_modules/generate-password/package.json +54 -28
- package/node_modules/get-caller-file/package.json +53 -27
- package/node_modules/get-intrinsic/package.json +124 -91
- package/node_modules/glob/package.json +68 -34
- package/node_modules/glob-parent/package.json +70 -27
- package/node_modules/has/package.json +55 -26
- package/node_modules/has-symbols/package.json +133 -104
- package/node_modules/has-unicode/package.json +52 -25
- package/node_modules/https-proxy-agent/package.json +59 -30
- package/node_modules/iconv-lite/package.json +77 -48
- package/node_modules/inflight/package.json +48 -20
- package/node_modules/inherits/package.json +54 -17
- package/node_modules/is-binary-path/package.json +75 -43
- package/node_modules/is-extglob/package.json +52 -22
- package/node_modules/is-fullwidth-code-point/package.json +79 -45
- package/node_modules/is-glob/package.json +68 -26
- package/node_modules/is-number/package.json +65 -26
- package/node_modules/jsftp/node_modules/debug/package.json +67 -28
- package/node_modules/jsftp/package.json +59 -22
- package/node_modules/json2csv/node_modules/commander/package.json +56 -25
- package/node_modules/json2csv/package.json +64 -37
- package/node_modules/jsonparse/package.json +53 -18
- package/node_modules/lodash/package.json +61 -15
- package/node_modules/lodash.get/package.json +67 -16
- package/node_modules/lru-cache/package.json +61 -27
- package/node_modules/make-dir/node_modules/semver/package.json +51 -20
- package/node_modules/make-dir/package.json +93 -62
- package/node_modules/maplex/package.json +54 -22
- package/node_modules/methods/package.json +64 -22
- package/node_modules/mime/package.json +48 -20
- package/node_modules/mime-db/package.json +67 -25
- package/node_modules/mime-types/package.json +64 -20
- package/node_modules/mimic-response/package.json +76 -45
- package/node_modules/minimatch/package.json +61 -25
- package/node_modules/minipass/package.json +64 -30
- package/node_modules/minizlib/package.json +59 -27
- package/node_modules/mkdirp/package.json +57 -27
- package/node_modules/ms/package.json +58 -24
- package/node_modules/multi-progress/package.json +46 -20
- package/node_modules/nan/package.json +87 -27
- package/node_modules/node-fetch/package.json +104 -77
- package/node_modules/nopt/package.json +54 -22
- package/node_modules/normalize-path/package.json +63 -25
- package/node_modules/npmlog/package.json +55 -23
- package/node_modules/object-assign/package.json +51 -20
- package/node_modules/object-inspect/package.json +81 -53
- package/node_modules/once/package.json +56 -19
- package/node_modules/parse-listing/package.json +56 -27
- package/node_modules/path-is-absolute/package.json +47 -16
- package/node_modules/picomatch/package.json +60 -28
- package/node_modules/progress/package.json +65 -21
- package/node_modules/qs/package.json +105 -78
- package/node_modules/readdirp/package.json +83 -47
- package/node_modules/require-directory/package.json +57 -29
- package/node_modules/rimraf/package.json +61 -23
- package/node_modules/rw/package.json +46 -19
- package/node_modules/safe-buffer/package.json +38 -10
- package/node_modules/safer-buffer/package.json +43 -18
- package/node_modules/semver/package.json +70 -36
- package/node_modules/set-blocking/package.json +56 -29
- package/node_modules/side-channel/package.json +98 -70
- package/node_modules/sift/package.json +62 -30
- package/node_modules/signal-exit/package.json +58 -29
- package/node_modules/simple-concat/package.json +46 -22
- package/node_modules/simple-get/package.json +33 -9
- package/node_modules/simple-swizzle/node_modules/is-arrayish/package.json +59 -28
- package/node_modules/simple-swizzle/package.json +57 -23
- package/node_modules/strangler/package.json +67 -39
- package/node_modules/stream-combiner/package.json +48 -15
- package/node_modules/string-tools/package.json +50 -16
- package/node_modules/string-width/package.json +97 -59
- package/node_modules/string_decoder/package.json +47 -18
- package/node_modules/strip-ansi/package.json +94 -57
- package/node_modules/superagent/node_modules/form-data/package.json +74 -42
- package/node_modules/superagent/node_modules/readable-stream/package.json +60 -32
- package/node_modules/superagent/package.json +59 -13
- package/node_modules/tar/package.json +59 -27
- package/node_modules/through/package.json +50 -17
- package/node_modules/to-regex-range/package.json +61 -25
- package/node_modules/tr46/package.json +51 -24
- package/node_modules/unorm/package.json +75 -34
- package/node_modules/util-deprecate/package.json +49 -19
- package/node_modules/uuid/package.json +102 -74
- package/node_modules/webidl-conversions/package.json +53 -18
- package/node_modules/whatwg-url/package.json +49 -15
- package/node_modules/wide-align/package.json +53 -21
- package/node_modules/wolfy87-eventemitter/package.json +49 -25
- package/node_modules/wrap-ansi/package.json +97 -65
- package/node_modules/wrappy/package.json +50 -21
- package/node_modules/y18n/package.json +73 -43
- package/node_modules/yallist/package.json +55 -20
- package/node_modules/yargs/package.json +99 -72
- package/node_modules/yargs-parser/package.json +83 -52
- package/package.json +2 -1
- package/src/commands/Client.js +2 -2
- package/src/commands/agent/apps.js +2 -1
- package/src/commands/agent/file.js +2 -1
- package/src/commands/agent/ready.js +2 -1
- package/src/commands/extensions/delete.js +2 -1
- package/src/commands/extensions/list.js +2 -1
- package/src/commands/extensions/load.js +2 -1
- package/src/commands/extensions/validate.js +2 -1
- package/src/commands/firmware/list.js +2 -1
- package/src/commands/firmware/load.js +2 -1
- package/src/commands/images/create.js +2 -1
- package/src/commands/images/delete.js +2 -1
- package/src/commands/images/list.js +2 -1
- package/src/commands/instances/Instance.js +27 -0
- package/src/commands/instances/create.js +11 -4
- package/src/commands/instances/delete.js +20 -5
- package/src/commands/instances/index.js +2 -1
- package/src/commands/instances/list.js +3 -2
- package/src/commands/instances/start.js +2 -1
- package/src/commands/instances/stop.js +2 -1
- package/src/commands/instances/upgrade.js +90 -0
- package/src/commands/login.js +14 -2
- package/src/commands/logout.js +2 -1
- package/src/commands/projects/create.js +2 -1
- package/src/commands/projects/delete.js +2 -1
- package/src/commands/projects/list.js +2 -1
- package/src/commands/webplayer/create.js +2 -1
- package/src/commands/webplayer/destroy.js +2 -1
- package/src/commands/webplayer/list.js +2 -1
- package/src/commands/webplayer/login.js +2 -1
- package/src/error.js +14 -1
- package/src/profile.js +1 -1
- package/src/utils.js +11 -4
- 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('
|
|
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}`)
|
|
@@ -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
|
+
}
|
package/src/commands/login.js
CHANGED
|
@@ -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('
|
|
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,
|
|
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 })
|
package/src/commands/logout.js
CHANGED
|
@@ -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('
|
|
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('
|
|
6
|
+
yargs.option('verbose', {
|
|
7
|
+
alias: 'v',
|
|
7
8
|
type: 'boolean',
|
|
8
9
|
describe: 'Console will receive verbose error output'
|
|
9
10
|
})
|
|
@@ -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('
|
|
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('
|
|
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('
|
|
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('
|
|
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('
|
|
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/profile.js
CHANGED
|
@@ -39,7 +39,7 @@ function readTrialConfig () {
|
|
|
39
39
|
|
|
40
40
|
function readProfile () {
|
|
41
41
|
if (!fs.existsSync(profilePath)) {
|
|
42
|
-
throw new Error(`Profile not found at ${profilePath}. Try to login with "corellium
|
|
42
|
+
throw new Error(`Profile not found at ${profilePath}. Try to login with "corellium login"`)
|
|
43
43
|
}
|
|
44
44
|
return JSON.parse(fs.readFileSync(profilePath))
|
|
45
45
|
}
|
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(
|
|
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
|
-
})
|