From 82bf437363f331deb1d611b96981017e24dfe95d Mon Sep 17 00:00:00 2001 From: sunil-lakshman <104969541+sunil-lakshman@users.noreply.github.com> Date: Mon, 29 Jul 2024 14:00:18 +0530 Subject: [PATCH 1/3] Added validation for management token before importing a stack data --- .../src/bootstrap/utils.ts | 17 +++++-- packages/contentstack-bootstrap/src/config.ts | 2 +- .../src/seed/contentstack/client.ts | 51 +++++++++++++++++++ packages/contentstack-seed/src/seed/index.ts | 39 +++++++++++++- 4 files changed, 103 insertions(+), 6 deletions(-) diff --git a/packages/contentstack-bootstrap/src/bootstrap/utils.ts b/packages/contentstack-bootstrap/src/bootstrap/utils.ts index 9c39c514c2..8bf041058b 100644 --- a/packages/contentstack-bootstrap/src/bootstrap/utils.ts +++ b/packages/contentstack-bootstrap/src/bootstrap/utils.ts @@ -67,6 +67,17 @@ export const setupEnvironments = async ( .stack({ api_key: api_key }) .managementToken() .create(managementBody); + if(!managementTokenResult.uid){ + cliux.print( + `Info: Failed to generate a management token.\nNote: Management token is not available in your plan. Please contact the admin for support.`, + { + color: 'yellow', + }, + ); + if ((await continueBootstrapCommand()) === 'no') { + return; + } + } } if (Array.isArray(environmentResult.items) && environmentResult.items.length > 0) { for (const environment of environmentResult.items) { @@ -229,15 +240,13 @@ const envFileHandler = async ( filePath = pathValidator(path.join(sanitizePath(clonedDirectory), sanitizePath(fileName))); content = `CONTENTSTACK_API_KEY=${environmentVariables.api_key}\nCONTENTSTACK_DELIVERY_TOKEN=${ environmentVariables.deliveryToken - }\n${ + }\nCONTENTSTACK_BRANCH=main${ livePreviewEnabled ? `\nCONTENTSTACK_PREVIEW_TOKEN=${ environmentVariables.preview_token || `''` }\nCONTENTSTACK_PREVIEW_HOST=${previewHost}\nCONTENTSTACK_APP_HOST=${appHost}\n` : '\n' - }CONTENTSTACK_ENVIRONMENT=${environmentVariables.environment}\nCONTENTSTACK_API_HOST=${ - customHost ? customHost : managementAPIHost - }${ + }CONTENTSTACK_ENVIRONMENT=${environmentVariables.environment}${ !isUSRegion && !customHost ? '\nCONTENTSTACK_REGION=' + region.name : '' }\nCONTENTSTACK_LIVE_PREVIEW=${livePreviewEnabled}\nCONTENTSTACK_LIVE_EDIT_TAGS=false\nCONTENTSTACK_API_HOST=${ customHost ? customHost : managementAPIHost diff --git a/packages/contentstack-bootstrap/src/config.ts b/packages/contentstack-bootstrap/src/config.ts index 63487ac76b..91f39e7251 100644 --- a/packages/contentstack-bootstrap/src/config.ts +++ b/packages/contentstack-bootstrap/src/config.ts @@ -50,7 +50,7 @@ const config: Configuration = { stack: 'contentstack/stack-contentstack-angular-modularblock-example', }, 'compass-app': { - source: 'SunilLsagar/universal-demo', + source: 'SunilLsagar/universal-demo-latest', stack: 'SunilLsagar/stack-universal-demo-latest', master_locale: 'en', }, diff --git a/packages/contentstack-seed/src/seed/contentstack/client.ts b/packages/contentstack-seed/src/seed/contentstack/client.ts index 178e8aa30f..4ef01bedc1 100644 --- a/packages/contentstack-seed/src/seed/contentstack/client.ts +++ b/packages/contentstack-seed/src/seed/contentstack/client.ts @@ -16,6 +16,12 @@ export interface Stack { org_uid: string; } +export interface ManagementToken { + response_code: string; + response_message: string; +} + + export interface CreateStackOptions { name: string; description: string; @@ -23,6 +29,20 @@ export interface CreateStackOptions { org_uid: string; } +export interface createManagementTokenOptions{ + name: string; + description: string; + expires_on: string; + scope: { + module: string; + acl: { + read: boolean; + write?: boolean; + }; + branches?: string[]; + }[]; +} + export default class ContentstackClient { instance: Promise; @@ -167,6 +187,37 @@ export default class ContentstackClient { } } + async createManagementToken(api_key: string, managementToken: any, options: createManagementTokenOptions): Promise { + try { + const client = await this.instance; + const body = { + token: { + name: options.name, + description: options.description, + scope: options.scope, + expires_on: options.expires_on, + }, + }; + + const response = await client.stack({ api_key: api_key, management_token: managementToken }).managementToken().create(body); + return { + response_code: response.errorCode, + response_message: response.errorMessage + }; + } catch (error: unknown) { + const typedError = error as { errorCode: string }; + + if (typedError.errorCode === '401') { + return { + response_code: '401', + response_message: 'You do not have access to create management tokens. Please try again or ask an Administrator for assistance.' + } + } + throw this.buildError(typedError); + } + + } + private buildError(error: any) { const message = error.errorMessage || error.response.data?.errorMessage || error.response.statusText; const status = error.status; diff --git a/packages/contentstack-seed/src/seed/index.ts b/packages/contentstack-seed/src/seed/index.ts index 6bbc512b4c..a027c363fa 100644 --- a/packages/contentstack-seed/src/seed/index.ts +++ b/packages/contentstack-seed/src/seed/index.ts @@ -184,9 +184,46 @@ export default class ContentModelSeeder { let count; const stack_details = await this.csClient.getStack(api_key); if(this.options.master_locale != stack_details.master_locale){ - cliux.print(`Compass app requires the master locale to be set to English (en).`); + cliux.print(`Compass app requires the master locale to be set to English (en).`,{ + color: "yellow", + bold: true, + }); return false; } + const managementBody = { + "name":"Checking roles for creating management token", + "description":"This is a compass app management token.", + "scope":[ + { + "module":"content_type", + "acl":{ + "read":true, + "write":true + } + }, + { + "module":"branch", + "branches":[ + "main" + ], + "acl":{ + "read":true + } + } + ], + "expires_on": "3000-01-01", + "is_email_notification_enabled":false + } + let managementTokenResult = await this.csClient.createManagementToken(api_key, this.managementToken, managementBody); + if(managementTokenResult.response_code == "161" || managementTokenResult.response_code == "401"){ + cliux.print( + `Info: Failed to generate a management token.\nNote: Management token is not available in your plan. Please contact the admin for support.`, + { + color: 'yellow', + }, + ); + return false; + } count = await this.csClient.getContentTypeCount(api_key, this.managementToken); if (count > 0 && this._options.skipStackConfirmation !== 'yes') { From 3ae332edff5fb9a0fcbbc5989725b7da7fede805 Mon Sep 17 00:00:00 2001 From: sunil-lakshman <104969541+sunil-lakshman@users.noreply.github.com> Date: Mon, 29 Jul 2024 16:37:24 +0530 Subject: [PATCH 2/3] Updated display error color to red --- packages/contentstack-seed/src/seed/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/contentstack-seed/src/seed/index.ts b/packages/contentstack-seed/src/seed/index.ts index a027c363fa..33204b40e9 100644 --- a/packages/contentstack-seed/src/seed/index.ts +++ b/packages/contentstack-seed/src/seed/index.ts @@ -219,7 +219,7 @@ export default class ContentModelSeeder { cliux.print( `Info: Failed to generate a management token.\nNote: Management token is not available in your plan. Please contact the admin for support.`, { - color: 'yellow', + color: 'red', }, ); return false; From 7fcf378fdd0482c85d5ba0b9ed2ac87a31bb0392 Mon Sep 17 00:00:00 2001 From: sunil-lakshman <104969541+sunil-lakshman@users.noreply.github.com> Date: Tue, 30 Jul 2024 13:10:27 +0530 Subject: [PATCH 3/3] Added optional chaining for managementTokenResult variable --- packages/contentstack-seed/src/seed/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/contentstack-seed/src/seed/index.ts b/packages/contentstack-seed/src/seed/index.ts index 33204b40e9..4223acb0a3 100644 --- a/packages/contentstack-seed/src/seed/index.ts +++ b/packages/contentstack-seed/src/seed/index.ts @@ -215,7 +215,7 @@ export default class ContentModelSeeder { "is_email_notification_enabled":false } let managementTokenResult = await this.csClient.createManagementToken(api_key, this.managementToken, managementBody); - if(managementTokenResult.response_code == "161" || managementTokenResult.response_code == "401"){ + if(managementTokenResult?.response_code == "161" || managementTokenResult?.response_code == "401"){ cliux.print( `Info: Failed to generate a management token.\nNote: Management token is not available in your plan. Please contact the admin for support.`, {