@contentstack/cli-auth 0.1.1-beta.3 → 1.0.1
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/LICENSE +21 -0
- package/README.md +62 -53
- package/lib/commands/auth/login.js +56 -0
- package/lib/commands/auth/logout.js +61 -0
- package/lib/commands/auth/tokens/add.js +142 -0
- package/lib/commands/auth/tokens/index.js +54 -0
- package/lib/commands/auth/tokens/remove.js +55 -0
- package/lib/commands/auth/whoami.js +27 -0
- package/lib/config/index.js +0 -0
- package/lib/interfaces/index.js +2 -0
- package/lib/utils/auth-handler.js +118 -0
- package/lib/utils/index.js +7 -0
- package/lib/utils/interactive.js +55 -0
- package/lib/utils/tokens-validation.js +141 -0
- package/messages/index.json +46 -42
- package/oclif.manifest.json +1 -1
- package/package.json +51 -28
- package/src/commands/auth/login.js +0 -50
- package/src/commands/auth/logout.js +0 -44
- package/src/commands/auth/tokens/add.js +0 -86
- package/src/commands/auth/tokens/index.js +0 -59
- package/src/commands/auth/tokens/remove.js +0 -60
- package/src/commands/auth/whoami.js +0 -19
- package/src/hooks/validate-authtoken.js +0 -19
- package/src/util/auth-handler.js +0 -108
- package/src/util/messages.js +0 -18
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
const {Command, flags} = require('@contentstack/cli-command')
|
|
2
|
-
const {cli} = require('cli-ux')
|
|
3
|
-
const chalk = require('chalk')
|
|
4
|
-
const {AuthHandler} = require('../../util/auth-handler')
|
|
5
|
-
const Configstore = require('configstore')
|
|
6
|
-
const Messages = require('../../util/messages')
|
|
7
|
-
const messages = new Messages('logout').msgs
|
|
8
|
-
|
|
9
|
-
class LogoutCommand extends Command {
|
|
10
|
-
async run() {
|
|
11
|
-
const logoutCommandFlags = this.parse(LogoutCommand).flags
|
|
12
|
-
let confirm = false
|
|
13
|
-
confirm = logoutCommandFlags.force ? true : await cli.confirm(messages.promptConfirmLogout)
|
|
14
|
-
const opts = {
|
|
15
|
-
contentstackClient: this.managementAPIClient,
|
|
16
|
-
}
|
|
17
|
-
const authHandler = new AuthHandler(opts)
|
|
18
|
-
const config = new Configstore('contentstack_cli')
|
|
19
|
-
try {
|
|
20
|
-
if (confirm) {
|
|
21
|
-
cli.log(messages.msgLoggingOut)
|
|
22
|
-
let authtoken = this.authToken
|
|
23
|
-
await authHandler.logout(authtoken)
|
|
24
|
-
config.delete('authtoken')
|
|
25
|
-
config.delete('email')
|
|
26
|
-
cli.log(chalk.green(messages.msgLogOutSuccess))
|
|
27
|
-
}
|
|
28
|
-
} catch (error) {
|
|
29
|
-
config.delete('authtoken')
|
|
30
|
-
config.delete('email')
|
|
31
|
-
cli.log(chalk.green(messages.msgLogOutSuccess))
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
LogoutCommand.description = messages.commandDesc
|
|
37
|
-
|
|
38
|
-
LogoutCommand.flags = {
|
|
39
|
-
force: flags.boolean({char: 'f', description: messages.flagForceDesc}),
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
LogoutCommand.aliases = ['logout']
|
|
43
|
-
|
|
44
|
-
module.exports = LogoutCommand
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
const {Command, flags} = require('@oclif/command')
|
|
2
|
-
const {cli} = require('cli-ux')
|
|
3
|
-
const chalk = require('chalk')
|
|
4
|
-
const debug = require('debug')('csdx:tokens:add')
|
|
5
|
-
const Configstore = require('configstore')
|
|
6
|
-
const Messages = require('../../../util/messages')
|
|
7
|
-
const messages = new Messages('add').msgs
|
|
8
|
-
|
|
9
|
-
const config = new Configstore('contentstack_cli')
|
|
10
|
-
|
|
11
|
-
class AddCommand extends Command {
|
|
12
|
-
async run() {
|
|
13
|
-
let isReplace = false
|
|
14
|
-
const addCommandFlags = this.parse(AddCommand).flags
|
|
15
|
-
let forced = addCommandFlags.force
|
|
16
|
-
let alias = addCommandFlags.alias
|
|
17
|
-
let apiKey = addCommandFlags['api-key']
|
|
18
|
-
let token = addCommandFlags.token
|
|
19
|
-
let isDelivery = addCommandFlags.delivery
|
|
20
|
-
let isManagement = addCommandFlags.management
|
|
21
|
-
let environment = addCommandFlags.environment
|
|
22
|
-
let configKeyTokens = 'tokens'
|
|
23
|
-
let type = (isDelivery || Boolean(environment)) ? 'delivery' : 'management'
|
|
24
|
-
debug(`Adding ${type} token`)
|
|
25
|
-
|
|
26
|
-
// eslint-disable-next-line no-warning-comments
|
|
27
|
-
// TODO: Handle condition where token and api combination matched
|
|
28
|
-
|
|
29
|
-
if (!alias)
|
|
30
|
-
alias = await cli.prompt(messages.promptTokenAlias)
|
|
31
|
-
isReplace = Boolean(config.get(`${configKeyTokens}.${alias}`))// get to Check if alias already present
|
|
32
|
-
|
|
33
|
-
if (isReplace && !forced) {
|
|
34
|
-
isReplace = true
|
|
35
|
-
const confirm = await cli.confirm(Messages.parse(messages.promptConfirmReplaceToken, alias))
|
|
36
|
-
if (!confirm)
|
|
37
|
-
this.exit()
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
if (!apiKey)
|
|
41
|
-
apiKey = await cli.prompt(messages.promptAPIKey)
|
|
42
|
-
if (!token)
|
|
43
|
-
token = await cli.prompt(Messages.parse(messages.promptToken, type))
|
|
44
|
-
if (isDelivery && !environment)
|
|
45
|
-
environment = await cli.prompt(messages.promptEnv)
|
|
46
|
-
|
|
47
|
-
if (isManagement)
|
|
48
|
-
config.set(`${configKeyTokens}.${alias}`, {token, apiKey, type})
|
|
49
|
-
else
|
|
50
|
-
config.set(`${configKeyTokens}.${alias}`, {token, apiKey, environment, type})
|
|
51
|
-
|
|
52
|
-
if (isReplace)
|
|
53
|
-
cli.log(chalk.green(Messages.parse(messages.msgReplacedTokenSuccess, alias)))
|
|
54
|
-
else
|
|
55
|
-
cli.log(chalk.green(Messages.parse(messages.msgAddTokenSuccess, alias)))
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
AddCommand.description = `${messages.commandDescription}
|
|
60
|
-
by default it adds management token if either of management or delivery flags are not set`
|
|
61
|
-
|
|
62
|
-
AddCommand.flags = {
|
|
63
|
-
alias: flags.string({char: 'a', description: messages.flagAliasDescription}),
|
|
64
|
-
delivery: flags.boolean({
|
|
65
|
-
char: 'd',
|
|
66
|
-
description: 'Set this while saving delivery token',
|
|
67
|
-
exclusive: ['management'],
|
|
68
|
-
}),
|
|
69
|
-
management: flags.boolean({
|
|
70
|
-
char: 'm',
|
|
71
|
-
description: 'Set this while saving management token',
|
|
72
|
-
exclusive: ['delivery', 'environment'],
|
|
73
|
-
}),
|
|
74
|
-
environment: flags.string({
|
|
75
|
-
char: 'e',
|
|
76
|
-
description: 'Environment name for delivery token',
|
|
77
|
-
exclusive: ['management'],
|
|
78
|
-
}),
|
|
79
|
-
'api-key': flags.string({char: 'k', description: messages.flagAPIKeyDescription}),
|
|
80
|
-
force: flags.boolean({char: 'f', description: messages.flagForceDescription}),
|
|
81
|
-
token: flags.string({char: 't', description: messages.flagTokenDescription, env: 'TOKEN'}),
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
AddCommand.aliases = ['tokens:add']
|
|
85
|
-
|
|
86
|
-
module.exports = AddCommand
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
const {Command} = require('@oclif/command')
|
|
2
|
-
const {cli} = require('cli-ux')
|
|
3
|
-
const Configstore = require('configstore')
|
|
4
|
-
// const chalk = require('chalk')
|
|
5
|
-
|
|
6
|
-
const config = new Configstore('contentstack_cli')
|
|
7
|
-
|
|
8
|
-
class TokenIndex extends Command {
|
|
9
|
-
async run() {
|
|
10
|
-
let managementTokens = config.get('tokens')
|
|
11
|
-
let tokenOptions = []
|
|
12
|
-
if (managementTokens && Object.keys(managementTokens).length > 0) {
|
|
13
|
-
Object.keys(managementTokens).forEach(function (item) {
|
|
14
|
-
tokenOptions.push({
|
|
15
|
-
alias: item,
|
|
16
|
-
token: managementTokens[item].token,
|
|
17
|
-
apiKey: managementTokens[item].apiKey,
|
|
18
|
-
environment: managementTokens[item].environment ? managementTokens[item].environment : '-',
|
|
19
|
-
type: managementTokens[item].type,
|
|
20
|
-
})
|
|
21
|
-
})
|
|
22
|
-
const {flags} = this.parse(TokenIndex)
|
|
23
|
-
|
|
24
|
-
cli.table(tokenOptions,
|
|
25
|
-
{
|
|
26
|
-
alias: {
|
|
27
|
-
minWidth: 7,
|
|
28
|
-
},
|
|
29
|
-
token: {
|
|
30
|
-
minWidth: 7,
|
|
31
|
-
},
|
|
32
|
-
apiKey: {
|
|
33
|
-
minWidth: 7,
|
|
34
|
-
},
|
|
35
|
-
environment: {
|
|
36
|
-
minWidth: 7,
|
|
37
|
-
},
|
|
38
|
-
type: {
|
|
39
|
-
minWidth: 7,
|
|
40
|
-
},
|
|
41
|
-
},
|
|
42
|
-
{
|
|
43
|
-
printLine: this.log,
|
|
44
|
-
...flags, // parsed flags
|
|
45
|
-
},
|
|
46
|
-
)
|
|
47
|
-
} else {
|
|
48
|
-
cli.log('No tokens are added. Use auth:tokens:add command to add tokens.')
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
TokenIndex.description = `Lists all existing tokens added to the session
|
|
54
|
-
`
|
|
55
|
-
TokenIndex.aliases = ['tokens']
|
|
56
|
-
|
|
57
|
-
TokenIndex.flags = cli.table.flags()
|
|
58
|
-
|
|
59
|
-
module.exports = TokenIndex
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
const {Command, flags} = require('@oclif/command')
|
|
2
|
-
const {cli} = require('cli-ux')
|
|
3
|
-
const Configstore = require('configstore')
|
|
4
|
-
const inquirer = require('inquirer')
|
|
5
|
-
const Messages = require('../../../util/messages')
|
|
6
|
-
const messages = new Messages('remove').msgs
|
|
7
|
-
|
|
8
|
-
const config = new Configstore('contentstack_cli')
|
|
9
|
-
|
|
10
|
-
class RemoveCommand extends Command {
|
|
11
|
-
async run() {
|
|
12
|
-
const removeCommandFlags = this.parse(RemoveCommand).flags
|
|
13
|
-
let alias = removeCommandFlags.alias
|
|
14
|
-
let ignore = removeCommandFlags.ignore
|
|
15
|
-
|
|
16
|
-
let token = config.get(`tokens.${alias}`)
|
|
17
|
-
const tokens = config.get('tokens')
|
|
18
|
-
let tokenOptions = []
|
|
19
|
-
if (token || ignore) {
|
|
20
|
-
config.delete(`tokens.${alias}`)
|
|
21
|
-
return cli.log(`"${alias}" token removed successfully!`)
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
if (tokens && Object.keys(tokens).length > 0) {
|
|
25
|
-
Object.keys(tokens).forEach(function (item) {
|
|
26
|
-
tokenOptions.push(`${item}: ${tokens[item].token} : ${tokens[item].apiKey}${tokens[item].environment ? ' : ' + tokens[item].environment + ' ' : ''}: ${tokens[item].type}`)
|
|
27
|
-
})
|
|
28
|
-
} else {
|
|
29
|
-
return cli.log('No tokens are added yet.')
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
let responses = await inquirer.prompt([{
|
|
33
|
-
name: 'selectedTokens',
|
|
34
|
-
message: 'Select tokens to remove.',
|
|
35
|
-
type: 'checkbox',
|
|
36
|
-
choices: tokenOptions,
|
|
37
|
-
}])
|
|
38
|
-
|
|
39
|
-
let selectedTokens = responses.selectedTokens
|
|
40
|
-
if (selectedTokens.length === 0) {
|
|
41
|
-
return
|
|
42
|
-
}
|
|
43
|
-
selectedTokens.forEach(element => {
|
|
44
|
-
let selectedToken = element.split(':')[0]
|
|
45
|
-
config.delete(`tokens.${selectedToken}`)
|
|
46
|
-
cli.log(Messages.parse(messages.msgRemoveTokenSuccess, selectedToken))
|
|
47
|
-
})
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
RemoveCommand.description = messages.commandDescription
|
|
52
|
-
|
|
53
|
-
RemoveCommand.flags = {
|
|
54
|
-
alias: flags.string({char: 'a', description: messages.flagAliasDescription}),
|
|
55
|
-
ignore: flags.boolean({char: 'i', description: messages.flagIgnoreDescription}),
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
RemoveCommand.aliases = ['tokens:remove']
|
|
59
|
-
|
|
60
|
-
module.exports = RemoveCommand
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
const {Command} = require('@contentstack/cli-command')
|
|
2
|
-
const chalk = require('chalk')
|
|
3
|
-
|
|
4
|
-
class WhoamiCommand extends Command {
|
|
5
|
-
async run() {
|
|
6
|
-
try {
|
|
7
|
-
this.log(`You are currently logged in with email: ${chalk.yellow(this.email)}`)
|
|
8
|
-
} catch (error) {
|
|
9
|
-
this.log(chalk.red(error.message))
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
WhoamiCommand.description = `Display current users email address
|
|
15
|
-
`
|
|
16
|
-
|
|
17
|
-
WhoamiCommand.aliases = ['whoami']
|
|
18
|
-
|
|
19
|
-
module.exports = WhoamiCommand
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
const {AuthHandler} = require('../util/auth-handler')
|
|
2
|
-
const LoginCommand = require('../commands/auth/login')
|
|
3
|
-
const {cli} = require('cli-ux')
|
|
4
|
-
|
|
5
|
-
module.exports = async function () {
|
|
6
|
-
try {
|
|
7
|
-
let authtoken = this.authToken
|
|
8
|
-
const opts = {
|
|
9
|
-
contentstackClient: this.contentstackClient,
|
|
10
|
-
}
|
|
11
|
-
const authHandler = new AuthHandler(opts)
|
|
12
|
-
await authHandler.validateAuthtoken(authtoken)
|
|
13
|
-
} catch (error) {
|
|
14
|
-
let confirm = await cli.confirm('Your authtoken is expired or not valid. Do you want to login again?')
|
|
15
|
-
if (confirm) {
|
|
16
|
-
await LoginCommand.run()
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
}
|
package/src/util/auth-handler.js
DELETED
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
const { cli } = require('cli-ux')
|
|
2
|
-
const inquirer = require('inquirer')
|
|
3
|
-
const chalk = require('chalk')
|
|
4
|
-
|
|
5
|
-
let client = {}
|
|
6
|
-
|
|
7
|
-
class AuthHandler {
|
|
8
|
-
constructor(opts) {
|
|
9
|
-
client = opts.contentstackClient
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
*
|
|
14
|
-
* Login into Contentstack
|
|
15
|
-
* @param {string} email Contentstack email address
|
|
16
|
-
* @param {string} password User's password for contentstack account
|
|
17
|
-
* @returns {Promise} Promise object returns authtoken on success
|
|
18
|
-
*/
|
|
19
|
-
async login(email, password, tfaToken) {
|
|
20
|
-
const loginPayload = {
|
|
21
|
-
email,
|
|
22
|
-
password
|
|
23
|
-
};
|
|
24
|
-
if (tfaToken) {
|
|
25
|
-
loginPayload.tfa_token = tfaToken;
|
|
26
|
-
}
|
|
27
|
-
return new Promise( (resolve, reject) => {
|
|
28
|
-
if (email && password) {
|
|
29
|
-
client.login(loginPayload).then(async result => {
|
|
30
|
-
// 2FA enabled
|
|
31
|
-
if (result.error_code === 294) {
|
|
32
|
-
const twoFactorResult = await this.twoFactorAuthentication(loginPayload);
|
|
33
|
-
resolve(twoFactorResult);
|
|
34
|
-
} else {
|
|
35
|
-
resolve(result.user);
|
|
36
|
-
}
|
|
37
|
-
}).catch(error => {
|
|
38
|
-
reject(error)
|
|
39
|
-
})
|
|
40
|
-
}
|
|
41
|
-
})
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
async twoFactorAuthentication(loginPayload) {
|
|
45
|
-
const actions = [{
|
|
46
|
-
type: 'list',
|
|
47
|
-
name: 'otpChannel',
|
|
48
|
-
message: "Two factor authentication enabled, please select a way to get the security code",
|
|
49
|
-
choices: [
|
|
50
|
-
{ name: 'Authy App', value: 'authy' },
|
|
51
|
-
{ name: 'SMS', value: 'sms' },
|
|
52
|
-
],
|
|
53
|
-
}];
|
|
54
|
-
|
|
55
|
-
const channelResponse = await inquirer.prompt(actions)
|
|
56
|
-
|
|
57
|
-
// need to send sms to the mobile
|
|
58
|
-
if (channelResponse.otpChannel === 'sms') {
|
|
59
|
-
await client.axiosInstance.post('/user/request_token_sms', { user: loginPayload });
|
|
60
|
-
cli.log(chalk.yellow("Security code sent to your mobile"))
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
const tokenResponse = await inquirer.prompt({
|
|
64
|
-
type: 'input',
|
|
65
|
-
message: 'Please provide the security code',
|
|
66
|
-
name: 'tfaToken',
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
return this.login(loginPayload.email, loginPayload.password, tokenResponse.tfaToken);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
*
|
|
74
|
-
* Logout from Contentstack
|
|
75
|
-
* @param {string} authtoken authtoken that needs to invalidated when logging out
|
|
76
|
-
* @returns {Promise} Promise object returns response object from Contentstack
|
|
77
|
-
*/
|
|
78
|
-
async logout(authtoken) {
|
|
79
|
-
return new Promise(function (resolve, reject) {
|
|
80
|
-
if (authtoken) {
|
|
81
|
-
client.logout(authtoken).then(function (response) {
|
|
82
|
-
return resolve(response)
|
|
83
|
-
}).catch(error => {
|
|
84
|
-
reject(error)
|
|
85
|
-
})
|
|
86
|
-
} else {
|
|
87
|
-
return resolve()
|
|
88
|
-
}
|
|
89
|
-
})
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
async validateAuthtoken(authtoken) {
|
|
93
|
-
return new Promise(function (resolve, reject) {
|
|
94
|
-
if (authtoken) {
|
|
95
|
-
client.login({token: authtoken})
|
|
96
|
-
client.getUser()
|
|
97
|
-
.then(user => {
|
|
98
|
-
return resolve(user)
|
|
99
|
-
}).catch(error => reject(error))
|
|
100
|
-
}
|
|
101
|
-
return resolve()
|
|
102
|
-
})
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
module.exports = {
|
|
107
|
-
AuthHandler, client,
|
|
108
|
-
}
|
package/src/util/messages.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
const messages = require('../../messages/index.json')
|
|
2
|
-
|
|
3
|
-
class Messages {
|
|
4
|
-
constructor(type) {
|
|
5
|
-
this.msgs = messages[type]
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
static parse(msg, ...substitutions) {
|
|
9
|
-
if (substitutions.length > 0) {
|
|
10
|
-
let callSite = msg.split('%s')
|
|
11
|
-
callSite.push('')
|
|
12
|
-
return String.raw({raw: callSite}, ...substitutions)
|
|
13
|
-
}
|
|
14
|
-
return msg
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
module.exports = Messages
|