@corellium/corellium-cli 1.0.4 → 1.0.7
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
})
|