Skip to content

Commit

Permalink
feat(commands): Add --management-token flag to login
Browse files Browse the repository at this point in the history
Added the --management-token flag to the login command. This helps when specifying the managementToken directly (e.g. for use in ci or headless systems).
  • Loading branch information
Johann authored Jul 1, 2019
1 parent 5c95715 commit f52a80e
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 33 deletions.
11 changes: 10 additions & 1 deletion docs/login/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,26 @@ Start a new session with our CLI tool.
As the CLI tool uses our Content Management API, you need to have an CMA access
token to use all the commands. This command will take care of that.

A browser window will open, which let's you login or signup to a Contentful account.
If no managementToken is supplied by using the `--management-token` flag,
a browser window will open, which let's you login or signup to a Contentful account.
As soon as are logged in, you have to press authorize the Contentful CLI tool
from within your browser which will afterwards display a freshly generated
secure CMA access token.

If a managementToken is supplied, any existing token will be **overwritten**.

The token will be stored in a `.contentfulrc.json` file within your user directory.

Running the command while logged in already will show your current token.

The logout is done via [contentful logout](../logout)

## Usage
```
Options:
--management-token, --mt Management token to use to login
```

## Example

```sh
Expand Down
88 changes: 56 additions & 32 deletions lib/cmds/login.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,54 +17,78 @@ export const command = 'login'

export const desc = 'Login to Contentful'

export async function login ({ context }) {
export const builder = yargs => {
return yargs
.usage('Usage: contentful login')
.option('management-token', {
alias: 'mt',
describe: 'Contentful management API token',
type: 'string'
})
.epilog(
[
'See more at:',
'https://github.com/contentful/contentful-cli/tree/master/docs/login',
'Copyright 2018 Contentful, this is a BETA release'
].join('\n')
)
}

export async function login ({ context, managementToken: managementTokenFlag }) {
const { managementToken } = context

if (managementToken) {
let token
if (managementTokenFlag) {
token = managementTokenFlag
} else {
if (managementToken) {
log()
log(`Looks like you already stored a management token on your system. ${chalk.dim(`(Located at ${await getConfigPath()})`)}`)
log(frame(`Your management token: ${managementToken}`))
log(`Maybe you want to ${codeStyle('contentful logout')}?`)
return managementToken
}

log(`A browser window will open where you will log in (or sign up if you don’t have an account), authorize this CLI tool and paste your ${highlightStyle('CMA token')} here:`)
log()
log(`Looks like you already stored a management token on your system. ${chalk.dim(`(Located at ${await getConfigPath()})`)}`)
log(frame(`Your management token: ${managementToken}`))
log(`Maybe you want to ${codeStyle('contentful logout')}?`)
return managementToken
}

log(`A browser window will open where you will log in (or sign up if you don’t have an account), authorize this CLI tool and paste your ${highlightStyle('CMA token')} here:`)
log()
const confirmed = await confirmation('Open a browser window now?')

const confirmed = await confirmation('Open a browser window now?')
if (!confirmed) {
log('Log in aborted by the user.')
return
}

if (!confirmed) {
log('Log in aborted by the user.')
return
}
// We open the browser window only on Windows and OSX since this might fail or open the wrong browser on Linux.
if (['win32', 'darwin'].includes(process.platform)) {
await opn(oAuthURL, {
wait: false
})
} else {
log(`Unable to open your browser automatically. Please open the following URI in your browser:\n\n${pathStyle(oAuthURL)}\n\n`)
}

// We open the browser window only on Windows and OSX since this might fail or open the wrong browser on Linux.
if (['win32', 'darwin'].includes(process.platform)) {
await opn(oAuthURL, {
wait: false
})
} else {
log(`Unable to open your browser automatically. Please open the following URI in your browser:\n\n${pathStyle(oAuthURL)}\n\n`)
}
const tokenAnswer = await inquirer.prompt([
{
type: 'input',
name: 'managementToken',
message: 'Paste your token here:',
validate: (val) => /^[a-zA-Z0-9_-]{43,64}$/i.test(val.trim()) // token is 43 to 64 cahracters and accept lower/uppercase caharacter plus `-` and `_`
}
])

const tokenAnswer = await inquirer.prompt([
{
type: 'input',
name: 'managementToken',
message: 'Paste your token here:',
validate: (val) => /^[a-zA-Z0-9_-]{43,64}$/i.test(val.trim()) // token is 43 to 64 cahracters and accept lower/uppercase caharacter plus `-` and `_`
}
])
token = tokenAnswer.managementToken
}

await setContext({
managementToken: tokenAnswer.managementToken
managementToken: token
})
await storeRuntimeConfig()
log()
log(`Great! Your ${highlightStyle('CMA token')} is now stored on your system. ${chalk.dim(`(Located at ${await getConfigPath()})`)}`)
log(`You can always run ${codeStyle('contentful logout')} to remove it.`)

return tokenAnswer.managementToken
return token
}

export const handler = handle(login)
9 changes: 9 additions & 0 deletions test/integration/cmds/login.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,12 @@ test('should be already loged in', done => {
.stdout(/Maybe you want to contentful logout\?/)
.end(done)
})

test('should login with management-token flag', done => {
app()
.run(`login --management-token ${process.env.CLI_E2E_CMA_TOKEN}`)
.code(0)
.stdout(/Great! Your CMA token is now stored on your system\./)
.stdout(/You can always run contentful logout to remove it\./)
.end(done)
})
9 changes: 9 additions & 0 deletions test/unit/cmds/login.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,12 @@ test('login - already logged in', async () => {
expect(setContext).not.toHaveBeenCalled()
expect(inquirer.prompt).not.toHaveBeenCalled()
})

test('login - with management-token flag', async () => {
const result = await loginHandler({context: {managementToken: 'token'}, ...mockedRcConfig})

expect(setContext).toHaveBeenCalledTimes(1)
expect(setContext.mock.calls[0][0]).toEqual(mockedRcConfig)
expect(result).toBe(mockedRcConfig.managementToken)
expect(inquirer.prompt).not.toHaveBeenCalled()
})

0 comments on commit f52a80e

Please sign in to comment.