@corellium/corellium-cli 1.1.0 → 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- package/package.json +2 -1
- package/src/{commands/agent → clients}/Agent.js +1 -1
- package/src/clients/Client.js +89 -0
- package/src/clients/Instance.js +84 -0
- package/src/{TrialAccount.js → clients/TrialAccount.js} +3 -3
- package/src/{commands/webplayer → clients}/Webplayer.js +2 -2
- package/src/commands/agent/apps.js +1 -1
- package/src/commands/agent/file.js +1 -1
- package/src/commands/agent/ready.js +1 -1
- package/src/commands/instances/index.js +1 -0
- package/src/commands/instances/netmon/disable.js +44 -0
- package/src/commands/instances/netmon/download.js +50 -0
- package/src/commands/instances/netmon/enable.js +72 -0
- package/src/commands/instances/netmon/index.js +15 -0
- package/src/commands/instances/netmon/stream.js +48 -0
- package/src/commands/instances/restoreBackup.js +1 -1
- package/src/commands/instances/rotate.js +1 -1
- package/src/commands/instances/start.js +18 -9
- package/src/commands/instances/upgrade.js +1 -1
- package/src/commands/signup.js +2 -2
- package/src/commands/webplayer/create.js +1 -1
- package/src/commands/webplayer/destroy.js +1 -1
- package/src/commands/webplayer/list.js +1 -1
- package/src/commands/webplayer/login.js +1 -1
- package/src/commands/Client.js +0 -45
- package/src/commands/instances/Instance.js +0 -35
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@corellium/corellium-cli",
|
3
|
-
"version": "1.1.
|
3
|
+
"version": "1.1.1",
|
4
4
|
"description": "Corellium CLI Tool",
|
5
5
|
"scripts": {
|
6
6
|
"corellium": "node index.js",
|
@@ -33,6 +33,7 @@
|
|
33
33
|
"progress": "^2.0.3",
|
34
34
|
"prompts": "^2.4.2",
|
35
35
|
"uuid": "^8.3.2",
|
36
|
+
"websocket-stream": "^5.5.2",
|
36
37
|
"xhr2": "^0.2.0",
|
37
38
|
"yargs": "^17.5.1"
|
38
39
|
},
|
@@ -0,0 +1,89 @@
|
|
1
|
+
const axios = require('axios').default
|
2
|
+
const { readProfile } = require('../profile')
|
3
|
+
const { createWriteStream } = require('fs')
|
4
|
+
const wsstream = require('websocket-stream')
|
5
|
+
|
6
|
+
/**
|
7
|
+
* Client Base class
|
8
|
+
*/
|
9
|
+
class Client {
|
10
|
+
constructor (argv) {
|
11
|
+
this.argv = Object.assign({}, argv)
|
12
|
+
this.project = argv.project || argv.projectId
|
13
|
+
this.instance = argv.instance || argv.instanceId
|
14
|
+
this._profile = readProfile()
|
15
|
+
this._version = require('../../package.json').version
|
16
|
+
}
|
17
|
+
|
18
|
+
/**
|
19
|
+
* @protected
|
20
|
+
* @returns default headers
|
21
|
+
*/
|
22
|
+
_headers = () => ({
|
23
|
+
Authorization: `Bearer ${this._profile.token}`,
|
24
|
+
'User-Agent': `corellium-cli v${this._version}`
|
25
|
+
})
|
26
|
+
|
27
|
+
/**
|
28
|
+
* Retrieve file stream
|
29
|
+
* @protected
|
30
|
+
* @param {string} path
|
31
|
+
* @param {PathLike} outputFile
|
32
|
+
* @returns {Promise<any>}
|
33
|
+
*/
|
34
|
+
_fetchStream = async (path, outputFile) => {
|
35
|
+
const response = await axios({
|
36
|
+
method: 'GET',
|
37
|
+
url: `${this._profile.endpoint}/api/${path}`,
|
38
|
+
headers: this._headers(),
|
39
|
+
responseType: 'stream'
|
40
|
+
})
|
41
|
+
|
42
|
+
const writeStream = createWriteStream(outputFile)
|
43
|
+
response.data.pipe(writeStream)
|
44
|
+
|
45
|
+
return new Promise((resolve, reject) => {
|
46
|
+
writeStream.on('finish', resolve)
|
47
|
+
writeStream.on('error', reject)
|
48
|
+
})
|
49
|
+
}
|
50
|
+
|
51
|
+
/**
|
52
|
+
* Get Websocket stream
|
53
|
+
* @protected
|
54
|
+
* @param {string} token
|
55
|
+
* @returns {wsstream.WebSocketDuplex}
|
56
|
+
*/
|
57
|
+
_fetchWSS = (token) => {
|
58
|
+
const url = `wss://${this._profile.endpoint}/api/v1/agent/${token}`
|
59
|
+
return wsstream(url, ['binary'])
|
60
|
+
}
|
61
|
+
|
62
|
+
/**
|
63
|
+
* Perform HTTP transaction
|
64
|
+
* @protected
|
65
|
+
* @param {string} method
|
66
|
+
* @param {string} path
|
67
|
+
* @param {object} data
|
68
|
+
* @returns {Promise<any>}
|
69
|
+
*/
|
70
|
+
_fetch = async (method, path, data) => {
|
71
|
+
const headers = this._headers()
|
72
|
+
let response
|
73
|
+
switch (method) {
|
74
|
+
case 'GET':
|
75
|
+
response = await axios.get(`${this._profile.endpoint}/api/${path}`, { headers })
|
76
|
+
break
|
77
|
+
case 'POST':
|
78
|
+
response = await axios.post(`${this._profile.endpoint}/api/${path}`, data, { headers })
|
79
|
+
break
|
80
|
+
case 'DELETE':
|
81
|
+
response = await axios.delete(`${this._profile.endpoint}/api/${path}`, { headers })
|
82
|
+
break
|
83
|
+
}
|
84
|
+
if (response.status >= 400) { throw new Error(response.statusText) }
|
85
|
+
return response.data || {}
|
86
|
+
}
|
87
|
+
}
|
88
|
+
|
89
|
+
module.exports = Client
|
@@ -0,0 +1,84 @@
|
|
1
|
+
const Client = require('./Client')
|
2
|
+
|
3
|
+
/**
|
4
|
+
* Instance class
|
5
|
+
*/
|
6
|
+
class InstanceCLI extends Client {
|
7
|
+
instanceBasePath = () => `v1/instances/${this.instance}`
|
8
|
+
preauthedBasePath = () => 'v1/preauthed'
|
9
|
+
|
10
|
+
/**
|
11
|
+
* Upgrade iOS version on instance
|
12
|
+
* @returns {Promise<any>}
|
13
|
+
*/
|
14
|
+
upgrade = async (options) => {
|
15
|
+
const { os, osbuild } = options
|
16
|
+
return await this._fetch('POST', `${this.instanceBasePath()}/upgrade`, { os, osbuild })
|
17
|
+
}
|
18
|
+
|
19
|
+
/**
|
20
|
+
* Get websocket stream from token
|
21
|
+
* @returns {wsstream.WebSocketDuplex}
|
22
|
+
*/
|
23
|
+
wss = (token) => {
|
24
|
+
return this._fetchWSS(token)
|
25
|
+
}
|
26
|
+
|
27
|
+
/**
|
28
|
+
* Start instance
|
29
|
+
*/
|
30
|
+
start = async (options) => {
|
31
|
+
const { sockcap, paused } = options
|
32
|
+
return await this._fetch('POST', `${this.instanceBasePath()}/start`, { sockcap, paused })
|
33
|
+
}
|
34
|
+
|
35
|
+
/**
|
36
|
+
* Restore backup to instance
|
37
|
+
* @returns {Promise<any>}
|
38
|
+
*/
|
39
|
+
restoreBackup = async () => {
|
40
|
+
return await this._fetch('POST', `${this.instanceBasePath()}/restoreBackup`)
|
41
|
+
}
|
42
|
+
|
43
|
+
/**
|
44
|
+
* Enable monitoring
|
45
|
+
* @returns {Promise<any>}
|
46
|
+
*/
|
47
|
+
enableMonitoring = async (options) => {
|
48
|
+
return await this._fetch('POST', `${this.instanceBasePath()}/netdump/enable`, options)
|
49
|
+
}
|
50
|
+
|
51
|
+
/**
|
52
|
+
* Disable monitoring
|
53
|
+
* @returns {Promise<any>}
|
54
|
+
*/
|
55
|
+
disableMonitoring = async () => {
|
56
|
+
return await this._fetch('POST', `${this.instanceBasePath()}/netdump/disable`)
|
57
|
+
}
|
58
|
+
|
59
|
+
/**
|
60
|
+
* Authorize pcap download
|
61
|
+
* @returns {Promise<any>}
|
62
|
+
*/
|
63
|
+
authorizePcap = async () => {
|
64
|
+
return await this._fetch('POST', `${this.instanceBasePath()}/netdump-authorize`)
|
65
|
+
}
|
66
|
+
|
67
|
+
/**
|
68
|
+
* Download file
|
69
|
+
* @returns {Promise<any>}
|
70
|
+
*/
|
71
|
+
download = async (token, file, outputFile) => {
|
72
|
+
return await this._fetchStream(`${this.preauthedBasePath()}/${token}/${file}`, outputFile)
|
73
|
+
}
|
74
|
+
|
75
|
+
/**
|
76
|
+
* Fetch instance information
|
77
|
+
* @returns {Promise<any>}
|
78
|
+
*/
|
79
|
+
info = async () => {
|
80
|
+
return await this._fetch('GET', `${this.instanceBasePath()}`, {})
|
81
|
+
}
|
82
|
+
}
|
83
|
+
|
84
|
+
module.exports = InstanceCLI
|
@@ -1,6 +1,6 @@
|
|
1
|
-
const Client = require('./
|
2
|
-
const util = require('
|
3
|
-
const { handler: login } = require('
|
1
|
+
const Client = require('./Client')
|
2
|
+
const util = require('../utils')
|
3
|
+
const { handler: login } = require('../commands/login')
|
4
4
|
|
5
5
|
class TrialAccount extends Client {
|
6
6
|
constructor (argv) {
|
@@ -0,0 +1,44 @@
|
|
1
|
+
const log = require('../../../logging')
|
2
|
+
const InstanceCLI = require('../../../clients/Instance')
|
3
|
+
|
4
|
+
async function builder (yargs) {
|
5
|
+
yargs
|
6
|
+
.positional('instanceId', {
|
7
|
+
type: 'string',
|
8
|
+
describe: 'Instance id',
|
9
|
+
demandOption: true
|
10
|
+
})
|
11
|
+
.option('verbose', {
|
12
|
+
alias: 'v',
|
13
|
+
type: 'boolean',
|
14
|
+
describe: 'Console will receive verbose error output',
|
15
|
+
demandOption: false
|
16
|
+
})
|
17
|
+
}
|
18
|
+
|
19
|
+
async function handler (argv) {
|
20
|
+
try {
|
21
|
+
const instance = new InstanceCLI(argv)
|
22
|
+
await instance.disableMonitoring()
|
23
|
+
log.info('Success')
|
24
|
+
} catch (e) {
|
25
|
+
if (e.response) {
|
26
|
+
log.error(`${e.response.status} ${e.response.data.error || e.response.statusText}`)
|
27
|
+
} else {
|
28
|
+
if (e.message) {
|
29
|
+
log.error(e.message)
|
30
|
+
} else {
|
31
|
+
log.error('Urecognized error, use --verbose for details')
|
32
|
+
}
|
33
|
+
}
|
34
|
+
|
35
|
+
if (argv.verbose) { log.error(JSON.stringify(e)) }
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
39
|
+
module.exports = {
|
40
|
+
builder,
|
41
|
+
handler,
|
42
|
+
command: 'disable <instanceId> [--verbose]',
|
43
|
+
describe: 'Disable network monitoring'
|
44
|
+
}
|
@@ -0,0 +1,50 @@
|
|
1
|
+
const log = require('../../../logging')
|
2
|
+
const InstanceCLI = require('../../../clients/Instance')
|
3
|
+
|
4
|
+
async function builder (yargs) {
|
5
|
+
yargs
|
6
|
+
.positional('instanceId', {
|
7
|
+
type: 'string',
|
8
|
+
describe: 'Instance id',
|
9
|
+
demandOption: true
|
10
|
+
})
|
11
|
+
.positional('outputFile', {
|
12
|
+
type: 'string',
|
13
|
+
describe: 'Path to output',
|
14
|
+
demandOption: true
|
15
|
+
})
|
16
|
+
.option('verbose', {
|
17
|
+
alias: 'v',
|
18
|
+
type: 'boolean',
|
19
|
+
describe: 'Console will receive verbose error output',
|
20
|
+
demandOption: false
|
21
|
+
})
|
22
|
+
}
|
23
|
+
|
24
|
+
async function handler (argv) {
|
25
|
+
try {
|
26
|
+
const instance = new InstanceCLI(argv)
|
27
|
+
const { token } = await instance.authorizePcap()
|
28
|
+
await instance.download(token, 'netdump.pcap', argv.outputFile)
|
29
|
+
log.info(`Success, pcap saved to ${argv.outputFile}`)
|
30
|
+
} catch (e) {
|
31
|
+
if (e.response) {
|
32
|
+
log.error(`${e.response.status} ${e.response.data.error || e.response.statusText}`)
|
33
|
+
} else {
|
34
|
+
if (e.message) {
|
35
|
+
log.error(e.message)
|
36
|
+
} else {
|
37
|
+
log.error('Urecognized error, use --verbose for details')
|
38
|
+
}
|
39
|
+
}
|
40
|
+
|
41
|
+
if (argv.verbose) { log.error(JSON.stringify(e)) }
|
42
|
+
}
|
43
|
+
}
|
44
|
+
|
45
|
+
module.exports = {
|
46
|
+
builder,
|
47
|
+
handler,
|
48
|
+
command: 'download <instanceId> <outputFile> [--verbose]',
|
49
|
+
describe: 'Download pcap file'
|
50
|
+
}
|
@@ -0,0 +1,72 @@
|
|
1
|
+
const log = require('../../../logging')
|
2
|
+
const InstanceCLI = require('../../../clients/Instance')
|
3
|
+
|
4
|
+
async function builder (yargs) {
|
5
|
+
yargs
|
6
|
+
.positional('instanceId', {
|
7
|
+
type: 'string',
|
8
|
+
describe: 'Instance id',
|
9
|
+
demandOption: true
|
10
|
+
})
|
11
|
+
.option('srcPorts', {
|
12
|
+
type: 'array',
|
13
|
+
describe: 'Source ports to filter'
|
14
|
+
})
|
15
|
+
.option('dstPorts', {
|
16
|
+
type: 'array',
|
17
|
+
describe: 'Destination ports to filter'
|
18
|
+
})
|
19
|
+
.option('ports', {
|
20
|
+
type: 'array',
|
21
|
+
describe: 'Source or destination ports to filter'
|
22
|
+
})
|
23
|
+
.option('processes', {
|
24
|
+
type: 'array',
|
25
|
+
describe: 'List of process names or pids to filter'
|
26
|
+
})
|
27
|
+
.option('portRanges', {
|
28
|
+
type: 'array',
|
29
|
+
describe: 'List of port ranges in that format \'[beginPort]-[endport]\''
|
30
|
+
})
|
31
|
+
.option('protocols', {
|
32
|
+
type: 'array',
|
33
|
+
describe: 'List of protocols'
|
34
|
+
})
|
35
|
+
.option('verbose', {
|
36
|
+
alias: 'v',
|
37
|
+
type: 'boolean',
|
38
|
+
describe: 'Console will receive verbose error output',
|
39
|
+
demandOption: false
|
40
|
+
})
|
41
|
+
}
|
42
|
+
|
43
|
+
async function handler (argv) {
|
44
|
+
try {
|
45
|
+
const { srcPorts, dstPorts, ports, processes, portRanges, protocols } = argv
|
46
|
+
|
47
|
+
const instance = new InstanceCLI(argv)
|
48
|
+
await instance.enableMonitoring({
|
49
|
+
srcPorts, dstPorts, ports, processes, portRanges, protocols
|
50
|
+
})
|
51
|
+
log.info('Success')
|
52
|
+
} catch (e) {
|
53
|
+
if (e.response) {
|
54
|
+
log.error(`${e.response.status} ${e.response.data.error || e.response.statusText}`)
|
55
|
+
} else {
|
56
|
+
if (e.message) {
|
57
|
+
log.error(e.message)
|
58
|
+
} else {
|
59
|
+
log.error('Urecognized error, use --verbose for details')
|
60
|
+
}
|
61
|
+
}
|
62
|
+
|
63
|
+
if (argv.verbose) { log.error(JSON.stringify(e)) }
|
64
|
+
}
|
65
|
+
}
|
66
|
+
|
67
|
+
module.exports = {
|
68
|
+
builder,
|
69
|
+
handler,
|
70
|
+
command: 'enable <instanceId> [--verbose]',
|
71
|
+
describe: 'Enable network monitoring'
|
72
|
+
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
const subcommands = [
|
2
|
+
require('./enable'),
|
3
|
+
require('./disable'),
|
4
|
+
require('./download'),
|
5
|
+
require('./stream')
|
6
|
+
]
|
7
|
+
|
8
|
+
let _yargs
|
9
|
+
|
10
|
+
module.exports = {
|
11
|
+
builder: yargs => (_yargs = yargs) && yargs.command(subcommands).scriptName(''),
|
12
|
+
handler: argv => !argv[1] && _yargs.showHelp(),
|
13
|
+
command: 'netmon',
|
14
|
+
describe: 'Network Monitoring related commands'
|
15
|
+
}
|
@@ -0,0 +1,48 @@
|
|
1
|
+
const log = require('../../../logging')
|
2
|
+
const InstanceCLI = require('../../../clients/Instance')
|
3
|
+
|
4
|
+
async function builder (yargs) {
|
5
|
+
yargs
|
6
|
+
.positional('instanceId', {
|
7
|
+
type: 'string',
|
8
|
+
describe: 'Instance id',
|
9
|
+
demandOption: true
|
10
|
+
})
|
11
|
+
.option('verbose', {
|
12
|
+
alias: 'v',
|
13
|
+
type: 'boolean',
|
14
|
+
describe: 'Console will receive verbose error output',
|
15
|
+
demandOption: false
|
16
|
+
})
|
17
|
+
}
|
18
|
+
|
19
|
+
async function handler (argv) {
|
20
|
+
try {
|
21
|
+
const instance = new InstanceCLI(argv)
|
22
|
+
const { netdump } = await instance.info()
|
23
|
+
if (netdump && netdump.enabled) {
|
24
|
+
instance.wss(netdump.info).pipe(process.stdout)
|
25
|
+
} else {
|
26
|
+
log.error('Network monitoring is not enabled')
|
27
|
+
}
|
28
|
+
} catch (e) {
|
29
|
+
if (e.response) {
|
30
|
+
log.error(`${e.response.status} ${e.response.data.error || e.response.statusText}`)
|
31
|
+
} else {
|
32
|
+
if (e.message) {
|
33
|
+
log.error(e.message)
|
34
|
+
} else {
|
35
|
+
log.error('Urecognized error, use --verbose for details')
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
39
|
+
if (argv.verbose) { log.error(JSON.stringify(e)) }
|
40
|
+
}
|
41
|
+
}
|
42
|
+
|
43
|
+
module.exports = {
|
44
|
+
builder,
|
45
|
+
handler,
|
46
|
+
command: 'stream <instanceId> [--verbose]',
|
47
|
+
describe: 'Stream monitoring events'
|
48
|
+
}
|
@@ -1,7 +1,7 @@
|
|
1
1
|
const { getErrorMessage } = require('../../error')
|
2
2
|
const asciiArt = require('ascii-art')
|
3
3
|
|
4
|
-
const Client = require('
|
4
|
+
const Client = require('../../clients/Client')
|
5
5
|
async function builder (yargs) {
|
6
6
|
yargs.positional('instanceId', {
|
7
7
|
type: 'string',
|
@@ -1,6 +1,7 @@
|
|
1
1
|
const { getErrorMessage } = require('../../error')
|
2
2
|
const asciiArt = require('ascii-art')
|
3
|
-
const {
|
3
|
+
const { waitForState } = require('../../utils')
|
4
|
+
const InstanceCLI = require('../../clients/Instance')
|
4
5
|
|
5
6
|
async function builder (yargs) {
|
6
7
|
yargs.positional('instanceId', {
|
@@ -17,25 +18,33 @@ async function builder (yargs) {
|
|
17
18
|
type: 'boolean',
|
18
19
|
describe: 'Wait for the instance to be fully started'
|
19
20
|
})
|
21
|
+
.option('paused', {
|
22
|
+
type: 'boolean',
|
23
|
+
describe: 'Start instance in a paused state'
|
24
|
+
})
|
25
|
+
.option('sockcap', {
|
26
|
+
type: 'boolean',
|
27
|
+
describe: 'Start sockcap add-on if loaded'
|
28
|
+
})
|
20
29
|
}
|
21
30
|
|
22
31
|
async function handler (argv) {
|
23
|
-
const
|
24
|
-
const
|
32
|
+
const { sockcap, paused } = argv
|
33
|
+
const instance = new InstanceCLI(argv)
|
25
34
|
try {
|
26
|
-
await
|
35
|
+
await instance.start({ sockcap, paused })
|
27
36
|
if (argv.wait) {
|
28
37
|
// Wait 60 attempts for the instance to be created (5 minutes)
|
29
|
-
await waitForState(instanceId,
|
38
|
+
await waitForState(argv.instanceId, instance.info.bind(instance), 'on', 60)
|
30
39
|
}
|
31
40
|
console.log(
|
32
|
-
asciiArt.style(`Successfully started instance ${instanceId}`, 'green', true)
|
41
|
+
asciiArt.style(`Successfully started instance ${argv.instanceId}`, 'green', true)
|
33
42
|
)
|
34
43
|
} catch (error) {
|
35
44
|
const errorMessage = getErrorMessage(error)
|
36
|
-
console.error(`Failed to start ${
|
45
|
+
console.error(`Failed to start ${argv.instance}: ${errorMessage}`)
|
37
46
|
|
38
|
-
if (argv.
|
47
|
+
if (argv.verbose) {
|
39
48
|
console.log(error)
|
40
49
|
}
|
41
50
|
}
|
@@ -44,6 +53,6 @@ async function handler (argv) {
|
|
44
53
|
module.exports = {
|
45
54
|
builder,
|
46
55
|
handler,
|
47
|
-
command: 'start <instanceId> [wait]',
|
56
|
+
command: 'start <instanceId> [--wait] [--verbose] [--paused] [--sockcap]',
|
48
57
|
describe: 'Start instance'
|
49
58
|
}
|
package/src/commands/signup.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
const TrialAccount = require('../TrialAccount')
|
1
|
+
const TrialAccount = require('../clients/TrialAccount')
|
2
2
|
const { makePassword, validateNonEmpty } = require('../utils')
|
3
3
|
const { getErrorMessage } = require('../error')
|
4
4
|
const log = require('../logging')
|
@@ -7,7 +7,7 @@ async function builder (yargs) {
|
|
7
7
|
yargs.options({
|
8
8
|
endpoint: {
|
9
9
|
type: 'input',
|
10
|
-
describe: 'Server endpoint e.g. https://app.
|
10
|
+
describe: 'Server endpoint e.g. https://app.corellium.co',
|
11
11
|
demandOption: true,
|
12
12
|
string: true,
|
13
13
|
validateNonEmpty
|
package/src/commands/Client.js
DELETED
@@ -1,45 +0,0 @@
|
|
1
|
-
const axios = require('axios').default
|
2
|
-
const { readProfile } = require('../profile')
|
3
|
-
|
4
|
-
/**
|
5
|
-
* Client Base class
|
6
|
-
*/
|
7
|
-
class Client {
|
8
|
-
constructor (argv) {
|
9
|
-
this.argv = Object.assign({}, argv)
|
10
|
-
this.project = argv.project || argv.projectId
|
11
|
-
this.instance = argv.instance || argv.instanceId
|
12
|
-
this._profile = readProfile()
|
13
|
-
}
|
14
|
-
|
15
|
-
/**
|
16
|
-
* Perform HTTP transaction
|
17
|
-
* @protected
|
18
|
-
* @param {string} method
|
19
|
-
* @param {string} path
|
20
|
-
* @param {object} data
|
21
|
-
* @returns {Promise<any>}
|
22
|
-
*/
|
23
|
-
_fetch = async (method, path, data) => {
|
24
|
-
const headers = {
|
25
|
-
Authorization: `Bearer ${this._profile.token}`,
|
26
|
-
'User-Agent': `corellium-cli v${require('../../package.json').version}`
|
27
|
-
}
|
28
|
-
let response
|
29
|
-
switch (method) {
|
30
|
-
case 'GET':
|
31
|
-
response = await axios.get(`${this._profile.endpoint}/api/${path}`, { headers })
|
32
|
-
break
|
33
|
-
case 'POST':
|
34
|
-
response = await axios.post(`${this._profile.endpoint}/api/${path}`, data, { headers })
|
35
|
-
break
|
36
|
-
case 'DELETE':
|
37
|
-
response = await axios.delete(`${this._profile.endpoint}/api/${path}`, { headers })
|
38
|
-
break
|
39
|
-
}
|
40
|
-
if (response.status >= 400) { throw new Error(response.statusText) }
|
41
|
-
return response.data || {}
|
42
|
-
}
|
43
|
-
}
|
44
|
-
|
45
|
-
module.exports = Client
|
@@ -1,35 +0,0 @@
|
|
1
|
-
const Client = require('../Client')
|
2
|
-
|
3
|
-
/**
|
4
|
-
* Instance class
|
5
|
-
*/
|
6
|
-
class InstanceCLI extends Client {
|
7
|
-
instanceBasePath = () => `v1/instances/${this.instance}`
|
8
|
-
|
9
|
-
/**
|
10
|
-
* Upgrade iOS version on instance
|
11
|
-
* @returns {Promise<any>}
|
12
|
-
*/
|
13
|
-
upgrade = async (options) => {
|
14
|
-
const { os, osbuild } = options
|
15
|
-
return await this._fetch('POST', `${this.instanceBasePath()}/upgrade`, { os, osbuild })
|
16
|
-
}
|
17
|
-
|
18
|
-
/**
|
19
|
-
* Restore backup to instance
|
20
|
-
* @returns {Promise<any>}
|
21
|
-
*/
|
22
|
-
restoreBackup = async () => {
|
23
|
-
return await this._fetch('POST', `${this.instanceBasePath()}/restoreBackup`)
|
24
|
-
}
|
25
|
-
|
26
|
-
/**
|
27
|
-
* Fetch instance information
|
28
|
-
* @returns {Promise<any>}
|
29
|
-
*/
|
30
|
-
info = async () => {
|
31
|
-
return await this._fetch('GET', `${this.instanceBasePath()}`, {})
|
32
|
-
}
|
33
|
-
}
|
34
|
-
|
35
|
-
module.exports = InstanceCLI
|