Skip to content

Commit

Permalink
feat(cli): use hidden prompt or stdin for auth:token command
Browse files Browse the repository at this point in the history
  • Loading branch information
olamothe committed Oct 16, 2023
1 parent 341d5a7 commit a7b7aa4
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 19 deletions.
23 changes: 11 additions & 12 deletions packages/cli/core/src/commands/auth/token.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {test} from '@oclif/test';
import {Config} from '@coveo/cli-commons/config/config';
import {AuthenticatedClient} from '@coveo/cli-commons/platform/authenticatedClient';
import {PlatformEnvironment} from '@coveo/cli-commons/platform/environment';
import {CliUx} from '@oclif/core';
const mockedConfig = jest.mocked(Config);
const mockedAuthenticatedClient = jest.mocked(AuthenticatedClient);

Expand Down Expand Up @@ -68,7 +69,8 @@ describe('auth:token', () => {
test
.stdout()
.stderr()
.command(['auth:token', '-e', environment, '-t', 'someToken'])
.stub(CliUx.ux, 'prompt', () => async () => 'someToken')
.command(['auth:token', '-e', environment])
.it(`writes the -e=${environment} flag to the configuration`, () => {
expect(mockConfigSet).toHaveBeenCalledWith('environment', environment);
});
Expand All @@ -78,7 +80,8 @@ describe('auth:token', () => {
test
.stdout()
.stderr()
.command(['auth:token', '-r', region, '-t', 'someToken'])
.stub(CliUx.ux, 'prompt', () => async () => 'someToken')
.command(['auth:token', '-r', region])
.it(`writes the -r=${region} flag and configuration`, () => {
expect(mockConfigSet).toHaveBeenCalledWith(
'region',
Expand All @@ -91,7 +94,8 @@ describe('auth:token', () => {
test
.stdout()
.stderr()
.command(['auth:token', '-t', 'this-is-the-token'])
.stub(CliUx.ux, 'prompt', () => async () => 'this-is-the-token')
.command(['auth:token'])
.it('save token from oauth service', () => {
expect(mockConfigSet).toHaveBeenCalledWith(
'accessToken',
Expand All @@ -101,20 +105,14 @@ describe('auth:token', () => {
});
});

test
.stdout()
.stderr()
.command(['auth:token'])
.exit(2)
.it('fails when the token flag is not set');

test
.stdout()
.stderr()
.do(() => {
mockGetHasAccessToOrg.mockReturnValueOnce(Promise.resolve(true));
})
.command(['auth:token', '-t', 'some-token'])
.stub(CliUx.ux, 'prompt', () => async () => 'some-token')
.command(['auth:token'])
.it(
'succeed when the organization and the token flags are valid',
(ctx) => {
Expand All @@ -130,7 +128,8 @@ describe('auth:token', () => {
})
.stdout()
.stderr()
.command(['auth:token', '-t', 'some-token'])
.stub(CliUx.ux, 'prompt', () => async () => 'some-token')
.command(['auth:token'])
.it(
'find the org associated with the token and saves it in the config',
() => {
Expand Down
23 changes: 16 additions & 7 deletions packages/cli/core/src/commands/auth/token.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import {CLICommand} from '@coveo/cli-commons/command/cliCommand';
import {Flags} from '@oclif/core';
import {CliUx, Flags} from '@oclif/core';
import {Config} from '@coveo/cli-commons/config/config';
import {AuthenticatedClient} from '@coveo/cli-commons/platform/authenticatedClient';
import {PlatformEnvironment} from '@coveo/cli-commons/platform/environment';
import {Region} from '@coveo/platform-client';
import {withEnvironment, withRegion} from '../../lib/flags/platformCommonFlags';
import {Trackable} from '@coveo/cli-commons/preconditions/trackable';
import {formatOrgId} from '@coveo/cli-commons/utils/ux';
import {readFile} from 'fs';
import {} from 'readline';
import {readFromStdinWithTimeout} from '../../lib/utils/process';

export default class Token extends CLICommand {
private configuration!: Config;
Expand All @@ -18,12 +21,11 @@ export default class Token extends CLICommand {
public static flags = {
...withRegion(),
...withEnvironment(),
token: Flags.string({
char: 't',
stdin: Flags.boolean({
char: 's',
description:
'The API-Key that shall be used to authenticate you to the organization. See <https://github.com/coveo/cli/wiki/Using-the-CLI-using-an-API-Key>.',
required: true,
helpValue: 'xxx-api-key',
'Read the token from stdin. Default to true when running in a CI environment.',
default: process.env.CI === 'true',
}),
};

Expand Down Expand Up @@ -52,7 +54,14 @@ export default class Token extends CLICommand {

private async saveToken() {
const {flags} = await this.parse(Token);
this.configuration.set('accessToken', flags.token);

const tok = flags.stdin
? await readFromStdinWithTimeout(1000)
: await CliUx.ux.prompt('Enter your access token: ', {
type: 'hide',
});

this.configuration.set('accessToken', tok);
this.configuration.set('anonymous', true);
}

Expand Down
17 changes: 17 additions & 0 deletions packages/cli/core/src/lib/utils/process.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,20 @@ export const handleForkedProcess = (subprocess: ChildProcess) => {
});
});
};

export const readFromStdinWithTimeout = (
timeoutMs: number
): Promise<string> => {
return new Promise(async (resolve, reject) => {
setTimeout(() => {
reject(`Read stdin timeout after ${timeoutMs}ms`);
}, timeoutMs);
const chunks: Buffer[] = [];

for await (const chunk of process.stdin) {
chunks.push(chunk);
}

resolve(Buffer.concat(chunks).toString('utf-8'));
});
};

0 comments on commit a7b7aa4

Please sign in to comment.