Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge staging to main #1077

Merged
merged 84 commits into from
Oct 13, 2023
Merged
Show file tree
Hide file tree
Changes from 38 commits
Commits
Show all changes
84 commits
Select commit Hold shift + click to select a range
cbbc774
fix: upgrade axios from 1.3.4 to 1.4.0
snyk-bot Sep 4, 2023
a11df20
Audit plugin basic plugin setup
antonyagustine Sep 6, 2023
6fc7199
Merge branch 'development' of https://github.com/contentstack/cli int…
antonyagustine Sep 6, 2023
947c08d
Readme updated
antonyagustine Sep 6, 2023
4e7ae86
Fix: audit command structure updated
antonyagustine Sep 7, 2023
083e32c
Code clean
antonyagustine Sep 7, 2023
32d1b29
Merge branch 'development' of https://github.com/contentstack/cli int…
antonyagustine Sep 8, 2023
2e4a6d1
Lock files updated
antonyagustine Sep 8, 2023
0dde53b
Fix: editor config removed, Missing package added
antonyagustine Sep 8, 2023
3b72f9b
Fix: bin dev script updated
antonyagustine Sep 8, 2023
3477297
Fix: cm:stacks:audit functionality for Content type [IP]
antonyagustine Sep 13, 2023
15cedcc
Merge branch 'development' of https://github.com/contentstack/cli int…
antonyagustine Sep 13, 2023
9883900
Merge branch 'feat/CS-41076' of https://github.com/contentstack/cli i…
antonyagustine Sep 13, 2023
ff84640
Missing type files added, error log fix
antonyagustine Sep 13, 2023
63f8512
Updated log messages
antonyagustine Sep 13, 2023
c88b729
Doc: Function definition and usage details added
antonyagustine Sep 13, 2023
5d190d3
Report output order change logic added, lint fixes, code clean
antonyagustine Sep 14, 2023
d0de43d
Fix: Exporting CSV report issue fixes
antonyagustine Sep 14, 2023
a1a828d
Merge pull request #1038 from contentstack/feat/CS-41075
antonyagustine Sep 14, 2023
128f2b5
Merge branch 'development' into feat/CS-41076
netrajpatel Sep 14, 2023
f7debce
Merge branch 'development' of https://github.com/contentstack/cli int…
antonyagustine Sep 15, 2023
78b6e6f
Fix: Updated the lock file
antonyagustine Sep 15, 2023
e25dda0
Merge branch 'development' of https://github.com/contentstack/cli int…
antonyagustine Sep 18, 2023
ca9ef20
Removed logger.inti from init and exporting class instead of instance
cs-raj Sep 20, 2023
a177859
Exported the instance of logger and provided the path of contentstack…
cs-raj Sep 20, 2023
7ad4371
Version Bump
cs-raj Sep 20, 2023
331b0eb
Merge branch 'development' of https://github.com/contentstack/cli int…
antonyagustine Sep 20, 2023
5ffa7b5
Feat: Global field audit functionality added
antonyagustine Sep 20, 2023
03d6773
npm audit fix
cs-raj Sep 21, 2023
76c88d2
Merge branch 'development' into bugfix/CS-41110
cs-raj Sep 21, 2023
fc3ef45
fix: resolved conflicts
Sep 21, 2023
841d3e5
fix: updated version
Sep 21, 2023
f726889
fix: moved axios to dev dependencies
Sep 21, 2023
f2ecbcc
Removed the file transport and uncommented the console transport
cs-raj Sep 21, 2023
cc1f726
Fix: Console removed
antonyagustine Sep 22, 2023
d4aa5e3
Merge branch 'development' into snyk-upgrade-6fbc5dd33c660134f03928c3…
netrajpatel Sep 22, 2023
8c5e903
Merge pull request #1053 from contentstack/feat/CS-41396
antonyagustine Sep 22, 2023
0c30183
Merge branch 'development' of https://github.com/contentstack/cli int…
antonyagustine Sep 25, 2023
565c74d
Lock files updated
antonyagustine Sep 25, 2023
10dc79e
Merge branch 'development' of https://github.com/contentstack/cli int…
antonyagustine Sep 25, 2023
467b490
fix: bumped package version
Sep 25, 2023
5766e2c
Merge remote-tracking branch 'origin/snyk-upgrade-6fbc5dd33c660134f03…
Sep 25, 2023
0dafdd5
fix: updated package-lock
Sep 26, 2023
be0cef2
Merge branch 'development' of https://github.com/contentstack/cli int…
antonyagustine Sep 27, 2023
0a1a525
Feat: Added the functionality to identify missing references in the E…
antonyagustine Sep 27, 2023
1c5f0fc
Doc: Readme updated
antonyagustine Sep 27, 2023
97452c3
Changed Logs so that a common log file is created
cs-raj Sep 28, 2023
8e6506a
Generating report logic updated
antonyagustine Sep 28, 2023
a065982
Changed the directory of base command
cs-raj Sep 28, 2023
c2709cb
Merge branch 'development' into bugfix/CS-41110
cs-raj Sep 28, 2023
744acc1
Merge pull request #1063 from contentstack/feat/CS-41397
antonyagustine Sep 28, 2023
a3f8902
Removed base-command from command folder and from contentstack cm:sta…
cs-raj Sep 29, 2023
2733edd
audit fix
cs-raj Sep 29, 2023
e7ee591
Replaced debug with info in logger
cs-raj Sep 29, 2023
8cadaf5
Merge branch 'development' into snyk-upgrade-6fbc5dd33c660134f03928c3…
Sep 29, 2023
59731c1
Doc: The document review text has been revised for UI text.
antonyagustine Oct 4, 2023
d473ef4
Merge pull request #1049 from contentstack/snyk-upgrade-6fbc5dd33c660…
netrajpatel Oct 4, 2023
c140179
Version bumped
Oct 5, 2023
ee05d12
Merge branch 'development' into bugfix/CS-41110
cs-raj Oct 5, 2023
acc4c6c
Merge pull request #1073 from contentstack/fix/version_bumps
netrajpatel Oct 5, 2023
f91714d
Merge branch 'development' into bugfix/CS-41110
cs-raj Oct 5, 2023
246fd94
Merge branch 'staging' into merge_fix
Oct 5, 2023
05d06c0
Merge pull request #1075 from contentstack/merge_fix
netrajpatel Oct 5, 2023
336ba87
Merge pull request #1070 from contentstack/development
netrajpatel Oct 5, 2023
91e846b
fix the log creation issue
cs-raj Oct 5, 2023
cc08d93
Merge branch 'main' into merge_fix
Oct 5, 2023
5442c34
Merge branch 'staging' into merge_fix
Oct 5, 2023
cec22a2
Merge pull request #1078 from contentstack/merge_fix
netrajpatel Oct 5, 2023
a17582c
Merge branch 'development' into bugfix/CS-41110
netrajpatel Oct 5, 2023
8d438c5
Bumped package versions
Oct 5, 2023
f88ef8a
Merge branch 'staging' into bugfix/CS-41110
Oct 5, 2023
82e079f
Merge pull request #1047 from contentstack/bugfix/CS-41110
netrajpatel Oct 5, 2023
1942bdb
Merge pull request #1080 from contentstack/development
netrajpatel Oct 5, 2023
67ebd6d
Merge branch 'development' of https://github.com/contentstack/cli int…
antonyagustine Oct 5, 2023
fdfe070
Fix: Entry undefined issue
antonyagustine Oct 5, 2023
f276de2
Fix: Missing packages added
antonyagustine Oct 5, 2023
f9750b7
Doc: Audit command description updated
antonyagustine Oct 5, 2023
d79fd20
Path validation added
antonyagustine Oct 6, 2023
ffb9845
Release workflow added, UI test fixes
antonyagustine Oct 6, 2023
507ef6e
Fix: Import issue fix | When more than 100 local exist query failed t…
antonyagustine Oct 6, 2023
afc6c10
Merge branch 'staging' into feat/audit-release
antonyagustine Oct 9, 2023
8c51c6e
Fix: Export - Cannot read properties of undefined (reading 'encrypt')
antonyagustine Oct 10, 2023
2d28985
Fix: SRE reported issue
antonyagustine Oct 12, 2023
267ae27
Merge pull request #1092 from contentstack/feat/audit-release
antonyagustine Oct 12, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44,873 changes: 24,677 additions & 20,196 deletions package-lock.json

Large diffs are not rendered by default.

33 changes: 14 additions & 19 deletions packages/contentstack-auth/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,44 +5,40 @@ It is Contentstack’s CLI plugin to perform authentication-related activities.
[![License](https://img.shields.io/npm/l/@contentstack/cli)](https://github.com/contentstack/cli/blob/main/LICENSE)

<!-- toc -->

- [@contentstack/cli-auth](#contentstackcli-auth)
- [Usage](#usage)
- [Commands](#commands)
* [@contentstack/cli-auth](#contentstackcli-auth)
* [Usage](#usage)
* [Commands](#commands)
<!-- tocstop -->

# Usage

<!-- usage -->

```sh-session
$ npm install -g @contentstack/cli-auth
$ csdx COMMAND
running command...
$ csdx (--version)
@contentstack/cli-auth/1.3.13 darwin-arm64 node-v20.7.0
@contentstack/cli-auth/1.3.14 darwin-x64 node-v20.8.0
$ csdx --help [COMMAND]
USAGE
$ csdx COMMAND
...
```

<!-- usagestop -->

# Commands

<!-- commands -->

- [`csdx auth:login`](#csdx-authlogin)
- [`csdx auth:logout`](#csdx-authlogout)
- [`csdx auth:tokens`](#csdx-authtokens)
- [`csdx auth:tokens:add [-a <value>] [--delivery] [--management] [-e <value>] [-k <value>] [-y] [--token <value>]`](#csdx-authtokensadd--a-value---delivery---management--e-value--k-value--y---token-value)
- [`csdx auth:tokens:remove`](#csdx-authtokensremove)
- [`csdx auth:whoami`](#csdx-authwhoami)
- [`csdx login`](#csdx-login)
- [`csdx logout`](#csdx-logout)
- [`csdx tokens`](#csdx-tokens)
- [`csdx whoami`](#csdx-whoami)
* [`csdx auth:login`](#csdx-authlogin)
* [`csdx auth:logout`](#csdx-authlogout)
* [`csdx auth:tokens`](#csdx-authtokens)
* [`csdx auth:tokens:add [-a <value>] [--delivery] [--management] [-e <value>] [-k <value>] [-y] [--token <value>]`](#csdx-authtokensadd--a-value---delivery---management--e-value--k-value--y---token-value)
* [`csdx auth:tokens:remove`](#csdx-authtokensremove)
* [`csdx auth:whoami`](#csdx-authwhoami)
* [`csdx login`](#csdx-login)
* [`csdx logout`](#csdx-logout)
* [`csdx tokens`](#csdx-tokens)
* [`csdx whoami`](#csdx-whoami)

## `csdx auth:login`

Expand Down Expand Up @@ -328,5 +324,4 @@ ALIASES
EXAMPLES
$ csdx auth:whoami
```

<!-- commandsstop -->
6 changes: 3 additions & 3 deletions packages/contentstack-auth/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@contentstack/cli-auth",
"description": "Contentstack CLI plugin for authentication activities",
"version": "1.3.13",
"version": "1.3.14",
"author": "Contentstack",
"bugs": "https://github.com/contentstack/cli/issues",
"scripts": {
Expand All @@ -22,8 +22,8 @@
"test:unit:report": "nyc --extension .ts mocha --forbid-only \"test/unit/**/*.test.ts\""
},
"dependencies": {
"@contentstack/cli-command": "~1.2.12",
"@contentstack/cli-utilities": "~1.5.2",
"@contentstack/cli-command": "~1.2.13",
"@contentstack/cli-utilities": "~1.5.3",
"chalk": "^4.0.0",
"debug": "^4.1.1",
"inquirer": "8.2.4",
Expand Down
59 changes: 59 additions & 0 deletions packages/contentstack-auth/src/base-command.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { Command } from '@contentstack/cli-command';
import { FlagInput, Flags, Interfaces, LoggerService } from '@contentstack/cli-utilities';

export type Args<T extends typeof Command> = Interfaces.InferredArgs<T['args']>;
export type Flags<T extends typeof Command> = Interfaces.InferredFlags<(typeof BaseCommand)['baseFlags'] & T['flags']>;

export abstract class BaseCommand<T extends typeof Command> extends Command {
public logger!: LoggerService;
protected args!: Args<T>;
protected flags!: Flags<T>;

// NOTE define flags that can be inherited by any command that extends BaseCommand
static baseFlags: FlagInput = {};

/**
* The `init` function initializes the command by parsing arguments and flags, registering search
* plugins, registering the configuration, and initializing the logger.
*/
public async init(): Promise<void> {
await super.init();
const { args, flags } = await this.parse({
flags: this.ctor.flags,
baseFlags: (super.ctor as typeof BaseCommand).baseFlags,
args: this.ctor.args,
strict: this.ctor.strict,
});
this.flags = flags as Flags<T>;
this.args = args as Args<T>;

// Init logger
this.logger = new LoggerService(process.cwd(), 'cli-log');
}

/**
* The catch function is used to handle errors from a command, either by adding custom logic or
* returning the parent class error handling.
* @param err - The `err` parameter is of type `Error & { exitCode?: number }`. This means that it is
* an object that extends the `Error` class and may also have an optional property `exitCode` of type
* `number`.
* @returns The parent class error handling is being returned.
*/
protected async catch(err: Error & { exitCode?: number }): Promise<any> {
// add any custom logic to handle errors from the command
// or simply return the parent class error handling
return super.catch(err);
}

/**
* The `finally` function is called after the `run` and `catch` functions, regardless of whether or not
* an error occurred.
* @param {Error | undefined} _ - The parameter "_" represents an error object or undefined.
* @returns The `finally` method is returning the result of calling the `finally` method of the
* superclass, which is a promise.
*/
protected async finally(_: Error | undefined): Promise<any> {
// called after run and catch regardless of whether or not the command errored
return super.finally(_);
}
}
11 changes: 5 additions & 6 deletions packages/contentstack-auth/src/commands/auth/login.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
import { Command } from '@contentstack/cli-command';
import {
logger,
cliux,
CLIError,
authHandler as oauthHandler,
flags,
managementSDKClient,
FlagInput
} from '@contentstack/cli-utilities';

import { User } from '../../interfaces';
import { authHandler, interactive } from '../../utils';
import { BaseCommand } from '../../base-command';

export default class LoginCommand extends Command {
export default class LoginCommand extends BaseCommand<typeof LoginCommand> {
static run; // to fix the test issue
static description = 'User sessions login';

Expand Down Expand Up @@ -61,7 +60,7 @@ export default class LoginCommand extends Command {
} else {
const username = loginFlags?.username || (await interactive.askUsername());
const password = loginFlags?.password || (await interactive.askPassword());
logger.debug('username', username);
this.logger.debug('username', username);
await this.login(username, password);
}
} catch (error) {
Expand All @@ -77,7 +76,7 @@ export default class LoginCommand extends Command {
errorMessage = error;
}
}
logger.error('login failed', errorMessage);
this.logger.error('login failed', errorMessage);
cliux.error('CLI_AUTH_LOGIN_FAILED');
cliux.error(errorMessage);
process.exit();
Expand All @@ -91,7 +90,7 @@ export default class LoginCommand extends Command {
throw new CLIError('Failed to login - invalid response');
}
await oauthHandler.setConfigData('basicAuth', user);
logger.info('successfully logged in');
this.logger.info('successfully logged in');
cliux.success('CLI_AUTH_LOGIN_SUCCESS');
} catch (error) {
throw error;
Expand Down
9 changes: 4 additions & 5 deletions packages/contentstack-auth/src/commands/auth/logout.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Command } from '@contentstack/cli-command';
import {
logger,
cliux,
configHandler,
printFlagDeprecation,
Expand All @@ -11,8 +10,8 @@ import {
} from '@contentstack/cli-utilities';

import { authHandler } from '../../utils';

export default class LogoutCommand extends Command {
import { BaseCommand } from '../../base-command';
export default class LogoutCommand extends BaseCommand<typeof LogoutCommand> {
static run;
static description = 'User session logout';
static examples = ['$ csdx auth:logout', '$ csdx auth:logout -y', '$ csdx auth:logout --yes'];
Expand Down Expand Up @@ -58,7 +57,7 @@ export default class LogoutCommand extends Command {
await oauthHandler.oauthLogout()
}
cliux.loader('');
logger.info('successfully logged out');
this.logger.info('successfully logged out');
cliux.success('CLI_AUTH_LOGOUT_SUCCESS');
} else {
cliux.success('CLI_AUTH_LOGOUT_ALREADY');
Expand All @@ -77,7 +76,7 @@ export default class LogoutCommand extends Command {
}
}

logger.error('Logout failed', errorMessage);
this.logger.error('Logout failed', errorMessage);
cliux.print('CLI_AUTH_LOGOUT_FAILED', { color: 'yellow' });
cliux.print(errorMessage, { color: 'red' });
} finally {
Expand Down
15 changes: 7 additions & 8 deletions packages/contentstack-auth/src/commands/auth/tokens/add.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import { Command } from '@contentstack/cli-command';
import {
logger,
cliux,
configHandler,
printFlagDeprecation,
flags,
FlagInput,
HttpClient,
messageHandler,
Flags,
} from '@contentstack/cli-utilities';
import { askTokenType } from '../../../utils/interactive';
export default class TokensAddCommand extends Command {
import { BaseCommand } from '../../../base-command';
export default class TokensAddCommand extends BaseCommand<typeof TokensAddCommand> {
static description = 'Adds management/delivery tokens to your session to use it with other CLI commands';

static examples = [
Expand All @@ -28,7 +29,7 @@ export default class TokensAddCommand extends Command {
];

static flags: FlagInput = {
alias: flags.string({ char: 'a', description: 'Name of the token alias' }),
alias: Flags.string({ char: 'a', description: 'Name of the token alias' }),
delivery: flags.boolean({
char: 'd',
description: 'Set this flag to save delivery token',
Expand Down Expand Up @@ -79,7 +80,6 @@ export default class TokensAddCommand extends Command {
'auth:tokens:add [-a <value>] [--delivery] [--management] [-e <value>] [-k <value>] [-y] [--token <value>]';

async run(): Promise<any> {
// @ts-ignore
const { flags: addTokenFlags } = await this.parse(TokensAddCommand);
let isAliasExist = false;
const skipAliasReplaceConfirmation = addTokenFlags.force || addTokenFlags.yes;
Expand All @@ -89,7 +89,6 @@ export default class TokensAddCommand extends Command {
let isDelivery = addTokenFlags.delivery;
let isManagement = addTokenFlags.management;
let environment = addTokenFlags.environment;
let branch = addTokenFlags.branch;
const configKeyTokens = 'tokens';

if (!isDelivery && !isManagement && !Boolean(environment)) {
Expand All @@ -100,7 +99,7 @@ export default class TokensAddCommand extends Command {

const type = isDelivery || Boolean(environment) ? 'delivery' : 'management';

logger.info(`adding ${type} token`);
this.logger.info(`adding ${type} token`);

try {
if (!alias) {
Expand All @@ -114,7 +113,7 @@ export default class TokensAddCommand extends Command {
name: 'confirm',
});
if (!shouldAliasReplace) {
logger.info('Exiting from the process of replacing the token');
this.logger.info('Exiting from the process of replacing the token');
cliux.print('CLI_AUTH_EXIT_PROCESS');
return;
}
Expand Down Expand Up @@ -160,7 +159,7 @@ export default class TokensAddCommand extends Command {
cliux.success('CLI_AUTH_TOKENS_ADD_SUCCESS');
}
} catch (error) {
logger.error('token add error', error.message);
this.logger.error('token add error', error.message);
cliux.print('CLI_AUTH_TOKENS_ADD_FAILED', { color: 'yellow' });
cliux.error(error.message.message ? error.message.message : error.message);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Command } from '@contentstack/cli-command';
import { logger, cliux, configHandler } from '@contentstack/cli-utilities';

export default class TokensListCommand extends Command {
import { cliux, configHandler } from '@contentstack/cli-utilities';
import { BaseCommand } from '../../../base-command';
export default class TokensListCommand extends BaseCommand<typeof TokensListCommand> {
static aliases = ['tokens'];
static examples = ['$ csdx auth:tokens'];
static description = 'Lists all existing tokens added to the session';
Expand Down Expand Up @@ -52,7 +52,7 @@ export default class TokensListCommand extends Command {
cliux.print('CLI_AUTH_TOKENS_LIST_NO_TOKENS');
}
} catch (error) {
logger.error('Token list error', error.message);
this.logger.error('Token list error', error.message);
cliux.print('CLI_AUTH_TOKENS_LIST_FAILED', { color: 'yellow' });
cliux.print(error.message, { color: 'red' });
}
Expand Down
14 changes: 10 additions & 4 deletions packages/contentstack-auth/src/commands/auth/tokens/remove.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { Command } from '@contentstack/cli-command';
import { logger, cliux, configHandler, flags, FlagInput } from '@contentstack/cli-utilities';
import { cliux, configHandler, flags, FlagInput } from '@contentstack/cli-utilities';
import { BaseCommand } from '../../../base-command';

export default class TokensRemoveCommand extends Command {
export default class TokensRemoveCommand extends BaseCommand<typeof TokensRemoveCommand> {
static description = 'Removes selected tokens';
static examples = ['$ csdx auth:tokens:remove', '$ csdx auth:tokens:remove -a <alias>'];
static flags: FlagInput = {
Expand Down Expand Up @@ -42,17 +43,22 @@ export default class TokensRemoveCommand extends Command {
choices: tokenOptions,
});

logger.debug('selected tokens', selectedTokens);
if (selectedTokens.length === 0) {
return;
}

selectedTokens.forEach((ele)=>{
this.logger.info('selected tokens',ele);
})

selectedTokens.forEach((element) => {
const selectedToken = element.split(':')[0];
configHandler.delete(`tokens.${selectedToken}`);
cliux.success('CLI_AUTH_TOKENS_REMOVE_SUCCESS');
this.logger.info('Token removed successfully !!', element);
});
} catch (error) {
logger.error('Token remove error', error.message);
this.logger.error('Token remove error', error.message);
cliux.print('CLI_AUTH_TOKENS_REMOVE_FAILED', { color: 'yellow' });
cliux.print(error.message, { color: 'red' });
}
Expand Down
9 changes: 5 additions & 4 deletions packages/contentstack-auth/src/commands/auth/whoami.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { Command } from '@contentstack/cli-command';
import { logger, cliux } from '@contentstack/cli-utilities';
import { cliux } from '@contentstack/cli-utilities';
import { BaseCommand } from '../../base-command';

export default class WhoamiCommand extends Command {
export default class WhoamiCommand extends BaseCommand<typeof WhoamiCommand> {
static description = 'Display current users email address';

static examples = ['$ csdx auth:whoami'];
Expand All @@ -13,12 +14,12 @@ export default class WhoamiCommand extends Command {
if (this.email) {
cliux.print('CLI_AUTH_WHOAMI_LOGGED_IN_AS', { color: 'white' });
cliux.print(this.email, { color: 'green' });
logger.info('Currently logged in user', this.email);
this.logger.info('Currently logged in user', this.email);
} else {
cliux.error('CLI_AUTH_WHOAMI_FAILED');
}
} catch (error) {
logger.error('whoami error', error.message);
this.logger.error('whoami error', error.message);
cliux.print('CLI_AUTH_WHOAMI_FAILED', { color: 'yellow' });
cliux.print(error.message, { color: 'red' });
}
Expand Down
Loading
Loading