Skip to content

Commit 0efd038

Browse files
authored
Merge pull request #71 from exoframejs/develop
Merge branch 'develop', prepare 0.22.0
2 parents b282127 + e946272 commit 0efd038

File tree

3 files changed

+367
-15
lines changed

3 files changed

+367
-15
lines changed

src/commands/token.js

Lines changed: 116 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,138 @@
11
// npm packages
22
const got = require('got');
33
const chalk = require('chalk');
4+
const inquirer = require('inquirer');
45

56
// our packages
67
const {userConfig, isLoggedIn, logout} = require('../config');
78

8-
exports.command = ['token'];
9-
exports.describe = 'generate new deployment token';
10-
exports.builder = {};
11-
exports.handler = async () => {
9+
exports.command = ['token [cmd]'];
10+
exports.describe = 'generate, list or remove deployment token';
11+
exports.builder = {
12+
cmd: {
13+
default: '',
14+
description: 'command to execute [ls | rm]',
15+
},
16+
};
17+
exports.handler = async args => {
1218
if (!isLoggedIn()) {
1319
return;
1420
}
1521

16-
console.log(chalk.bold('Generating new deployment token for:'), userConfig.endpoint);
17-
1822
// services request url
1923
const remoteUrl = `${userConfig.endpoint}/deployToken`;
24+
// get command
25+
const {cmd} = args;
26+
// if remove or ls - fetch tokens from remote, then do work
27+
if (cmd === 'ls' || cmd === 'rm') {
28+
console.log(
29+
chalk.bold(`${cmd === 'ls' ? 'Listing' : 'Removing'} deployment token${cmd === 'ls' ? 's' : ''} for:`),
30+
userConfig.endpoint
31+
);
32+
33+
// get tokens from server
34+
// construct shared request params
35+
const options = {
36+
method: 'GET',
37+
headers: {
38+
Authorization: `Bearer ${userConfig.token}`,
39+
},
40+
json: true,
41+
};
42+
// try sending request
43+
let tokens = [];
44+
try {
45+
const {body} = await got(remoteUrl, options);
46+
tokens = body.tokens;
47+
} catch (e) {
48+
// if authorization is expired/broken/etc
49+
if (e.statusCode === 401) {
50+
logout(userConfig);
51+
console.log(chalk.red('Error: authorization expired!'), 'Please, relogin and try again.');
52+
return;
53+
}
54+
55+
console.log(chalk.red('Error getting deployment tokens:'), e.toString());
56+
return;
57+
}
58+
59+
if (cmd === 'ls') {
60+
console.log(chalk.bold('Got generated tokens:'));
61+
console.log('');
62+
tokens.map(t =>
63+
console.log(` > ${chalk.green(t.tokenName)} ${chalk.gray(`[${new Date(t.meta.created).toLocaleString()}]`)}`)
64+
);
65+
if (!tokens.length) {
66+
console.log(' > No deployment tokens available!');
67+
}
68+
return;
69+
}
70+
71+
const prompts = [];
72+
prompts.push({
73+
type: 'list',
74+
name: 'rmToken',
75+
message: 'Choose token to remove:',
76+
choices: tokens.map(t => t.tokenName),
77+
});
78+
const {rmToken} = await inquirer.prompt(prompts);
79+
80+
// construct shared request params
81+
const rmOptions = {
82+
method: 'DELETE',
83+
headers: {
84+
Authorization: `Bearer ${userConfig.token}`,
85+
},
86+
json: true,
87+
body: {
88+
tokenName: rmToken,
89+
},
90+
};
91+
try {
92+
const {body, statusCode} = await got(remoteUrl, rmOptions);
93+
if (statusCode !== 204) {
94+
console.log(chalk.red('Error removing deployment token!'), body.reason || 'Please try again!');
95+
return;
96+
}
97+
console.log(chalk.green('Deployment token successfully removed!'));
98+
} catch (e) {
99+
// if authorization is expired/broken/etc
100+
if (e.statusCode === 401) {
101+
logout(userConfig);
102+
console.log(chalk.red('Error: authorization expired!'), 'Please, relogin and try again.');
103+
return;
104+
}
105+
106+
console.log(chalk.red('Error getting deployment tokens:'), e.toString());
107+
return;
108+
}
109+
110+
return;
111+
}
112+
113+
console.log(chalk.bold('Generating new deployment token for:'), userConfig.endpoint);
114+
115+
// ask for token name
116+
const prompts = [];
117+
prompts.push({
118+
type: 'input',
119+
name: 'tokenName',
120+
message: 'Token name:',
121+
validate: input => input && input.length > 0,
122+
filter: input => input.trim(),
123+
});
124+
const {tokenName} = await inquirer.prompt(prompts);
125+
20126
// construct shared request params
21127
const options = {
128+
method: 'POST',
22129
headers: {
23130
Authorization: `Bearer ${userConfig.token}`,
24131
},
25132
json: true,
133+
body: {
134+
tokenName,
135+
},
26136
};
27137
// try sending request
28138
try {

test/remove.js

Lines changed: 90 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ module.exports = () => {
1313
// test removal
1414
tap.test('Should remove', t => {
1515
// handle correct request
16-
const rmServer = nock('http://localhost:8080').post(`/remove/${id}`).reply(204);
16+
const rmServer = nock('http://localhost:8080')
17+
.post(`/remove/${id}`)
18+
.reply(204);
1719
// spy on console
1820
const consoleSpy = sinon.spy(console, 'log');
1921
// execute login
@@ -30,12 +32,98 @@ module.exports = () => {
3032
});
3133
});
3234

35+
// test removal error
36+
tap.test('Should show remove error', t => {
37+
// handle correct request
38+
const rmServer = nock('http://localhost:8080')
39+
.post(`/remove/${id}`)
40+
.reply(500);
41+
// spy on console
42+
const consoleSpy = sinon.spy(console, 'log');
43+
// execute login
44+
remove({id}).then(() => {
45+
// make sure log in was successful
46+
// check that server was called
47+
t.ok(rmServer.isDone());
48+
// first check console output
49+
t.deepEqual(
50+
consoleSpy.args,
51+
[
52+
['Removing deployment:', id],
53+
['Error removing project:', 'HTTPError: Response code 500 (Internal Server Error)'],
54+
],
55+
'Correct log output'
56+
);
57+
// restore console
58+
console.log.restore();
59+
rmServer.done();
60+
t.end();
61+
});
62+
});
63+
64+
// test removal error
65+
tap.test('Should show not found error', t => {
66+
// handle correct request
67+
const rmServer = nock('http://localhost:8080')
68+
.post(`/remove/${id}`)
69+
.reply(404);
70+
// spy on console
71+
const consoleSpy = sinon.spy(console, 'log');
72+
// execute login
73+
remove({id}).then(() => {
74+
// make sure log in was successful
75+
// check that server was called
76+
t.ok(rmServer.isDone());
77+
// first check console output
78+
t.deepEqual(
79+
consoleSpy.args,
80+
[
81+
['Removing deployment:', id],
82+
['Error: container was not found!', 'Please, check deployment ID and try again.'],
83+
],
84+
'Correct log output'
85+
);
86+
// restore console
87+
console.log.restore();
88+
rmServer.done();
89+
t.end();
90+
});
91+
});
92+
93+
// test removal error on incorrect success code
94+
tap.test('Should show not found error', t => {
95+
// handle correct request
96+
const rmServer = nock('http://localhost:8080')
97+
.post(`/remove/${id}`)
98+
.reply(200);
99+
// spy on console
100+
const consoleSpy = sinon.spy(console, 'log');
101+
// execute login
102+
remove({id}).then(() => {
103+
// make sure log in was successful
104+
// check that server was called
105+
t.ok(rmServer.isDone());
106+
// first check console output
107+
t.deepEqual(
108+
consoleSpy.args,
109+
[['Removing deployment:', id], ['Error!', 'Could not remove the deployment.']],
110+
'Correct log output'
111+
);
112+
// restore console
113+
console.log.restore();
114+
rmServer.done();
115+
t.end();
116+
});
117+
});
118+
33119
// test
34120
tap.test('Should deauth on 401', t => {
35121
// copy original config for restoration
36122
const originalConfig = Object.assign({}, userConfig);
37123
// handle correct request
38-
const rmServer = nock('http://localhost:8080').post(`/remove/${id}`).reply(401);
124+
const rmServer = nock('http://localhost:8080')
125+
.post(`/remove/${id}`)
126+
.reply(401);
39127
// spy on console
40128
const consoleSpy = sinon.spy(console, 'log');
41129
// execute login

0 commit comments

Comments
 (0)