From 34317da8971a884971f925e2d571344dad899fad Mon Sep 17 00:00:00 2001 From: Misha Tiurin Date: Wed, 3 Sep 2025 17:12:01 +0200 Subject: [PATCH 01/15] WIP Add license check to setup flow TODO pause the flow --- src/plugins/setup.ts | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/plugins/setup.ts b/src/plugins/setup.ts index 68c6f92..ceeb4ca 100644 --- a/src/plugins/setup.ts +++ b/src/plugins/setup.ts @@ -5,6 +5,7 @@ import { commands, ProgressLocation, window } from "vscode"; import { createPlugin } from "../plugins.ts"; import { checkIsAuthenticated, + checkIsLicenseValid, requestAuthentication, saveAuthToken, } from "../utils/authenticate.ts"; @@ -121,8 +122,6 @@ export default createPlugin( progress.report({ message: "Waiting for authentication response from the browser...", - // message: "Waiting for browser response...", - // message: "Waiting for authentication response...", }); const { authToken } = await minDelay( requestAuthentication(context, cancellationToken), @@ -145,7 +144,6 @@ export default createPlugin( ///////////////////////////////////////////////////////////////////// progress.report({ - // message: "Authenticating...", message: "Authenticating to file...", }); await minDelay(saveAuthToken(authToken, outputChannel)); @@ -167,6 +165,21 @@ export default createPlugin( } } + ///////////////////////////////////////////////////////////////////// + progress.report({ message: "Checking LocalStack license..." }); + const licenseIsValid = await minDelay( + checkIsLicenseValid(outputChannel), + ); + if (licenseIsValid) { + progress.report({ message: "License verified succesfully..." }); + } else { + progress.report({ + message: + "License is not valid or not assigned, please check License settings page...", + }); + commands.executeCommand("localstack.openLicensePage"); + } + ///////////////////////////////////////////////////////////////////// progress.report({ message: "Configuring AWS profiles...", From b5fe840e2633133767a2f5260f8578beb86a0b81 Mon Sep 17 00:00:00 2001 From: Misha Tiurin Date: Wed, 3 Sep 2025 17:14:16 +0200 Subject: [PATCH 02/15] Return false in case of license check error `undefined` return value was used in case of command error, however setup flow requires a definite outcome - either license is valid or any other outcome. --- src/utils/authenticate.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/utils/authenticate.ts b/src/utils/authenticate.ts index a53abcc..1924c8c 100644 --- a/src/utils/authenticate.ts +++ b/src/utils/authenticate.ts @@ -1,4 +1,3 @@ -import { createHash } from "node:crypto"; import * as fs from "node:fs/promises"; import * as os from "node:os"; import * as path from "node:path"; @@ -125,7 +124,7 @@ export async function checkIsLicenseValid(outputChannel: LogOutputChannel) { } catch (error) { outputChannel.error(error instanceof Error ? error : String(error)); - return undefined; + return false; } } From af4c6d6370357d0b4eba6eafa25dfe6e0f30438e Mon Sep 17 00:00:00 2001 From: Misha Tiurin Date: Thu, 4 Sep 2025 03:03:34 +0200 Subject: [PATCH 03/15] Add repeating license check to setup flow --- src/plugins/setup.ts | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/plugins/setup.ts b/src/plugins/setup.ts index ceeb4ca..f2bb902 100644 --- a/src/plugins/setup.ts +++ b/src/plugins/setup.ts @@ -1,6 +1,5 @@ -import os from "node:os"; - import { commands, ProgressLocation, window } from "vscode"; +import type { LogOutputChannel } from "vscode"; import { createPlugin } from "../plugins.ts"; import { @@ -167,17 +166,23 @@ export default createPlugin( ///////////////////////////////////////////////////////////////////// progress.report({ message: "Checking LocalStack license..." }); + + //TODO try to activate the license first + const licenseIsValid = await minDelay( checkIsLicenseValid(outputChannel), ); if (licenseIsValid) { - progress.report({ message: "License verified succesfully..." }); + progress.report({ + message: "License verified successfully...", + }); } else { progress.report({ message: "License is not valid or not assigned, please check License settings page...", }); commands.executeCommand("localstack.openLicensePage"); + await checkLicenseUntilValid(outputChannel); } ///////////////////////////////////////////////////////////////////// @@ -238,3 +243,18 @@ export default createPlugin( } }, ); + +async function checkLicenseUntilValid( + outputChannel: LogOutputChannel, +): Promise { + while (true) { + const licenseIsValid = await checkIsLicenseValid(outputChannel); + if (licenseIsValid) { + break; + } + //TODO try to activate the license + + // Wait 2 seconds before trying again + await new Promise((resolve) => setTimeout(resolve, 2000)); + } +} From 84e964e616343e4d70936e32284109d5aabc60e2 Mon Sep 17 00:00:00 2001 From: Misha Tiurin Date: Thu, 4 Sep 2025 03:48:53 +0200 Subject: [PATCH 04/15] WIP Add license activation TODO move to the right modules --- src/plugins/setup.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/plugins/setup.ts b/src/plugins/setup.ts index f2bb902..a5c821f 100644 --- a/src/plugins/setup.ts +++ b/src/plugins/setup.ts @@ -11,6 +11,7 @@ import { import { configureAwsProfiles } from "../utils/configure-aws.ts"; import { runInstallProcess } from "../utils/install.ts"; import { minDelay } from "../utils/promises.ts"; +import {execLocalStack} from "../utils/cli.ts"; export default createPlugin( ({ context, outputChannel, setupStatusTracker, telemetry }) => { @@ -167,7 +168,9 @@ export default createPlugin( ///////////////////////////////////////////////////////////////////// progress.report({ message: "Checking LocalStack license..." }); - //TODO try to activate the license first + const licenseActivateResponse = await execLocalStack(["license", "activate"], { + outputChannel, + }); const licenseIsValid = await minDelay( checkIsLicenseValid(outputChannel), @@ -252,7 +255,9 @@ async function checkLicenseUntilValid( if (licenseIsValid) { break; } - //TODO try to activate the license + const licenseActivateResponse = await execLocalStack(["license", "activate"], { + outputChannel, + }); // Wait 2 seconds before trying again await new Promise((resolve) => setTimeout(resolve, 2000)); From 1561709df35cf74328fddee263a9e6e0ec4134ee Mon Sep 17 00:00:00 2001 From: Misha Tiurin Date: Thu, 4 Sep 2025 11:48:47 +0200 Subject: [PATCH 05/15] Remove unused variable --- src/plugins/setup.ts | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/plugins/setup.ts b/src/plugins/setup.ts index a5c821f..762d794 100644 --- a/src/plugins/setup.ts +++ b/src/plugins/setup.ts @@ -8,10 +8,10 @@ import { requestAuthentication, saveAuthToken, } from "../utils/authenticate.ts"; +import { execLocalStack } from "../utils/cli.ts"; import { configureAwsProfiles } from "../utils/configure-aws.ts"; import { runInstallProcess } from "../utils/install.ts"; import { minDelay } from "../utils/promises.ts"; -import {execLocalStack} from "../utils/cli.ts"; export default createPlugin( ({ context, outputChannel, setupStatusTracker, telemetry }) => { @@ -168,10 +168,9 @@ export default createPlugin( ///////////////////////////////////////////////////////////////////// progress.report({ message: "Checking LocalStack license..." }); - const licenseActivateResponse = await execLocalStack(["license", "activate"], { - outputChannel, - }); - + await execLocalStack(["license", "activate"], { + outputChannel, + }); const licenseIsValid = await minDelay( checkIsLicenseValid(outputChannel), ); @@ -182,7 +181,7 @@ export default createPlugin( } else { progress.report({ message: - "License is not valid or not assigned, please check License settings page...", + "License is not valid or not assigned. Open License settings page to activate it.", }); commands.executeCommand("localstack.openLicensePage"); await checkLicenseUntilValid(outputChannel); @@ -255,10 +254,9 @@ async function checkLicenseUntilValid( if (licenseIsValid) { break; } - const licenseActivateResponse = await execLocalStack(["license", "activate"], { - outputChannel, - }); - + await execLocalStack(["license", "activate"], { + outputChannel, + }); // Wait 2 seconds before trying again await new Promise((resolve) => setTimeout(resolve, 2000)); } From c9299f7a9b65607ffe40021a85adbc0299e3308a Mon Sep 17 00:00:00 2001 From: Misha Tiurin Date: Thu, 4 Sep 2025 11:50:35 +0200 Subject: [PATCH 06/15] Add comment about activation --- src/plugins/setup.ts | 7 +++++++ src/utils/promises.ts | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/plugins/setup.ts b/src/plugins/setup.ts index 762d794..1e27366 100644 --- a/src/plugins/setup.ts +++ b/src/plugins/setup.ts @@ -168,6 +168,10 @@ export default createPlugin( ///////////////////////////////////////////////////////////////////// progress.report({ message: "Checking LocalStack license..." }); + // If an auth token has just been obtained or LocalStack has never been started, + // then there will be no license info to be reported by `localstack license info`. + // Also, an expired license could be cached. + // Activating the license pre-emptively to know its state during the setup process. await execLocalStack(["license", "activate"], { outputChannel, }); @@ -183,9 +187,12 @@ export default createPlugin( message: "License is not valid or not assigned. Open License settings page to activate it.", }); + commands.executeCommand("localstack.openLicensePage"); + await checkLicenseUntilValid(outputChannel); } + //TODO add telemetry ///////////////////////////////////////////////////////////////////// progress.report({ diff --git a/src/utils/promises.ts b/src/utils/promises.ts index cc1bf9a..157133a 100644 --- a/src/utils/promises.ts +++ b/src/utils/promises.ts @@ -1,9 +1,9 @@ import pMinDelay from "p-min-delay"; /** - * Setting up a minimum wait time of 1s allows users + * Setting up a minimum wait time allows users * to visually grasp the text before it goes away, if - * the task was fast (less than 0.5s). + * the task was faster than the minimum wait time. */ const MIN_TIME_BETWEEN_STEPS_MS = 500; From 019df5f93185fbf14482c7620cce2aa25aad61e6 Mon Sep 17 00:00:00 2001 From: Misha Tiurin Date: Thu, 4 Sep 2025 11:52:16 +0200 Subject: [PATCH 07/15] Reduce license check period to one second --- src/plugins/setup.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/setup.ts b/src/plugins/setup.ts index 1e27366..292d989 100644 --- a/src/plugins/setup.ts +++ b/src/plugins/setup.ts @@ -264,7 +264,7 @@ async function checkLicenseUntilValid( await execLocalStack(["license", "activate"], { outputChannel, }); - // Wait 2 seconds before trying again - await new Promise((resolve) => setTimeout(resolve, 2000)); + // Wait before trying again + await new Promise((resolve) => setTimeout(resolve, 1000)); } } From ea0b13a29cc37058b95675fa65db5198f146762a Mon Sep 17 00:00:00 2001 From: Misha Tiurin Date: Thu, 4 Sep 2025 12:19:53 +0200 Subject: [PATCH 08/15] Move license-related code to a separate module --- src/plugins/setup.ts | 30 +++++++----------------------- src/utils/authenticate.ts | 16 ---------------- src/utils/license.ts | 38 ++++++++++++++++++++++++++++++++++++++ src/utils/manage.ts | 2 +- 4 files changed, 46 insertions(+), 40 deletions(-) create mode 100644 src/utils/license.ts diff --git a/src/plugins/setup.ts b/src/plugins/setup.ts index 292d989..c155f06 100644 --- a/src/plugins/setup.ts +++ b/src/plugins/setup.ts @@ -1,16 +1,18 @@ import { commands, ProgressLocation, window } from "vscode"; -import type { LogOutputChannel } from "vscode"; import { createPlugin } from "../plugins.ts"; import { checkIsAuthenticated, - checkIsLicenseValid, requestAuthentication, saveAuthToken, } from "../utils/authenticate.ts"; -import { execLocalStack } from "../utils/cli.ts"; import { configureAwsProfiles } from "../utils/configure-aws.ts"; import { runInstallProcess } from "../utils/install.ts"; +import { + activateLicense, + checkIsLicenseValid, + activateLicenseUntilValid, +} from "../utils/license.ts"; import { minDelay } from "../utils/promises.ts"; export default createPlugin( @@ -172,9 +174,7 @@ export default createPlugin( // then there will be no license info to be reported by `localstack license info`. // Also, an expired license could be cached. // Activating the license pre-emptively to know its state during the setup process. - await execLocalStack(["license", "activate"], { - outputChannel, - }); + await activateLicense(outputChannel); const licenseIsValid = await minDelay( checkIsLicenseValid(outputChannel), ); @@ -190,7 +190,7 @@ export default createPlugin( commands.executeCommand("localstack.openLicensePage"); - await checkLicenseUntilValid(outputChannel); + await activateLicenseUntilValid(outputChannel); } //TODO add telemetry @@ -252,19 +252,3 @@ export default createPlugin( } }, ); - -async function checkLicenseUntilValid( - outputChannel: LogOutputChannel, -): Promise { - while (true) { - const licenseIsValid = await checkIsLicenseValid(outputChannel); - if (licenseIsValid) { - break; - } - await execLocalStack(["license", "activate"], { - outputChannel, - }); - // Wait before trying again - await new Promise((resolve) => setTimeout(resolve, 1000)); - } -} diff --git a/src/utils/authenticate.ts b/src/utils/authenticate.ts index 1924c8c..41131c6 100644 --- a/src/utils/authenticate.ts +++ b/src/utils/authenticate.ts @@ -10,7 +10,6 @@ import type { import { env, Uri, window } from "vscode"; import { assertIsError } from "./assert.ts"; -import { execLocalStack } from "./cli.ts"; /** * Registers a {@link UriHandler} that waits for an authentication token from the browser, @@ -113,21 +112,6 @@ export async function saveAuthToken( } } -const LICENSE_VALIDITY_MARKER = "license validity: valid"; - -export async function checkIsLicenseValid(outputChannel: LogOutputChannel) { - try { - const licenseInfoResponse = await execLocalStack(["license", "info"], { - outputChannel, - }); - return licenseInfoResponse.stdout.includes(LICENSE_VALIDITY_MARKER); - } catch (error) { - outputChannel.error(error instanceof Error ? error : String(error)); - - return false; - } -} - /** * Checks if the user is authenticated by validating the stored auth token. * diff --git a/src/utils/license.ts b/src/utils/license.ts new file mode 100644 index 0000000..d548aae --- /dev/null +++ b/src/utils/license.ts @@ -0,0 +1,38 @@ +import type { LogOutputChannel } from "vscode"; + +import { execLocalStack } from "./cli.ts"; + +const LICENSE_VALIDITY_MARKER = "license validity: valid"; + +export async function checkIsLicenseValid(outputChannel: LogOutputChannel) { + try { + const licenseInfoResponse = await execLocalStack(["license", "info"], { + outputChannel, + }); + return licenseInfoResponse.stdout.includes(LICENSE_VALIDITY_MARKER); + } catch (error) { + outputChannel.error(error instanceof Error ? error : String(error)); + + return false; + } +} + +export async function activateLicense(outputChannel: LogOutputChannel) { + await execLocalStack(["license", "activate"], { + outputChannel, + }); +} + +export async function activateLicenseUntilValid( + outputChannel: LogOutputChannel, +): Promise { + while (true) { + const licenseIsValid = await checkIsLicenseValid(outputChannel); + if (licenseIsValid) { + break; + } + await activateLicense(outputChannel); + // Wait before trying again + await new Promise((resolve) => setTimeout(resolve, 1000)); + } +} diff --git a/src/utils/manage.ts b/src/utils/manage.ts index 42eae83..563a212 100644 --- a/src/utils/manage.ts +++ b/src/utils/manage.ts @@ -2,9 +2,9 @@ import { v7 as uuidv7 } from "uuid"; import type { ExtensionContext, LogOutputChannel, MessageItem } from "vscode"; import { commands, env, Uri, window } from "vscode"; -import { checkIsLicenseValid } from "./authenticate.ts"; import { spawnLocalStack } from "./cli.ts"; import { exec } from "./exec.ts"; +import { checkIsLicenseValid } from "./license.ts"; import type { Telemetry } from "./telemetry.ts"; export type LocalstackStatus = "running" | "starting" | "stopping" | "stopped"; From 416a049856f1da0d8ec0b43b7ef8d80d2b02f5c5 Mon Sep 17 00:00:00 2001 From: Misha Tiurin Date: Thu, 4 Sep 2025 12:23:47 +0200 Subject: [PATCH 09/15] Add error message on pop-up cancel --- src/utils/manage.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/utils/manage.ts b/src/utils/manage.ts index 563a212..153159f 100644 --- a/src/utils/manage.ts +++ b/src/utils/manage.ts @@ -183,7 +183,12 @@ export async function stopLocalStack( export async function openLicensePage() { const url = new URL("https://app.localstack.cloud/settings/auth-tokens"); - await env.openExternal(Uri.parse(url.toString())); + const openSuccessful = await env.openExternal(Uri.parse(url.toString())); + if (!openSuccessful) { + window.showErrorMessage( + `Open LocalStack License page in browser by entering the URL manually: ${url.toString()}`, + ); + } } async function showInformationMessage( From 04808adef48811379d46daf99742f49cfdbd96c8 Mon Sep 17 00:00:00 2001 From: Misha Tiurin Date: Thu, 4 Sep 2025 12:27:12 +0200 Subject: [PATCH 10/15] Add license check to setup required --- src/utils/setup.ts | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/utils/setup.ts b/src/utils/setup.ts index 62238b0..2a46ab5 100644 --- a/src/utils/setup.ts +++ b/src/utils/setup.ts @@ -3,17 +3,20 @@ import type { LogOutputChannel } from "vscode"; import { checkIsAuthenticated } from "./authenticate.ts"; import { checkIsProfileConfigured } from "./configure-aws.ts"; import { checkLocalstackInstalled } from "./install.ts"; +import { checkIsLicenseValid } from "./license.ts"; export async function checkIsSetupRequired( outputChannel: LogOutputChannel, ): Promise { - const [isInstalled, isAuthenticated, isProfileConfigured] = await Promise.all( - [ + const [isInstalled, isAuthenticated, isLicenseValid, isProfileConfigured] = + await Promise.all([ checkLocalstackInstalled(outputChannel), checkIsAuthenticated(), + checkIsLicenseValid(outputChannel), checkIsProfileConfigured(), - ], - ); + ]); - return !isInstalled || !isAuthenticated || !isProfileConfigured; + return ( + !isInstalled || !isAuthenticated || !isLicenseValid || !isProfileConfigured + ); } From 2a06895aa6f58c78bf9ca5aaa69278e5773284e5 Mon Sep 17 00:00:00 2001 From: Misha Tiurin Date: Thu, 4 Sep 2025 12:50:33 +0200 Subject: [PATCH 11/15] Add try-catch around activation --- src/utils/license.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/utils/license.ts b/src/utils/license.ts index d548aae..38dabb0 100644 --- a/src/utils/license.ts +++ b/src/utils/license.ts @@ -18,9 +18,13 @@ export async function checkIsLicenseValid(outputChannel: LogOutputChannel) { } export async function activateLicense(outputChannel: LogOutputChannel) { - await execLocalStack(["license", "activate"], { - outputChannel, - }); + try { + await execLocalStack(["license", "activate"], { + outputChannel, + }); + } catch (error) { + outputChannel.error(error instanceof Error ? error : String(error)); + } } export async function activateLicenseUntilValid( From e90d1e499de7cbc834a65e721e7672e9cd0de644 Mon Sep 17 00:00:00 2001 From: Misha Tiurin Date: Thu, 4 Sep 2025 14:46:27 +0200 Subject: [PATCH 12/15] Chain initial activation and license check It is a single action in user's eyes so should be wrapped within one single `minDelay` --- src/plugins/setup.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/plugins/setup.ts b/src/plugins/setup.ts index c155f06..37bb476 100644 --- a/src/plugins/setup.ts +++ b/src/plugins/setup.ts @@ -176,7 +176,9 @@ export default createPlugin( // Activating the license pre-emptively to know its state during the setup process. await activateLicense(outputChannel); const licenseIsValid = await minDelay( - checkIsLicenseValid(outputChannel), + activateLicense(outputChannel).then(() => + checkIsLicenseValid(outputChannel), + ), ); if (licenseIsValid) { progress.report({ From b2cd21415378aac66e85517180bac3a69b6e1c08 Mon Sep 17 00:00:00 2001 From: Misha Tiurin Date: Thu, 4 Sep 2025 14:50:52 +0200 Subject: [PATCH 13/15] Use cancellation token --- src/plugins/setup.ts | 10 +++++++++- src/utils/license.ts | 6 +++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/plugins/setup.ts b/src/plugins/setup.ts index 37bb476..b1598a9 100644 --- a/src/plugins/setup.ts +++ b/src/plugins/setup.ts @@ -192,8 +192,16 @@ export default createPlugin( commands.executeCommand("localstack.openLicensePage"); - await activateLicenseUntilValid(outputChannel); + await activateLicenseUntilValid( + outputChannel, + cancellationToken, + ); + } + + if (cancellationToken.isCancellationRequested) { + return; } + //TODO add telemetry ///////////////////////////////////////////////////////////////////// diff --git a/src/utils/license.ts b/src/utils/license.ts index 38dabb0..e41350f 100644 --- a/src/utils/license.ts +++ b/src/utils/license.ts @@ -1,4 +1,4 @@ -import type { LogOutputChannel } from "vscode"; +import type { CancellationToken, LogOutputChannel } from "vscode"; import { execLocalStack } from "./cli.ts"; @@ -29,8 +29,12 @@ export async function activateLicense(outputChannel: LogOutputChannel) { export async function activateLicenseUntilValid( outputChannel: LogOutputChannel, + cancellationToken: CancellationToken, ): Promise { while (true) { + if (cancellationToken.isCancellationRequested) { + break; + } const licenseIsValid = await checkIsLicenseValid(outputChannel); if (licenseIsValid) { break; From d3293a7f6207a43498d30cb48a9affbffc42e6f6 Mon Sep 17 00:00:00 2001 From: Misha Tiurin <650819+tiurin@users.noreply.github.com> Date: Thu, 4 Sep 2025 15:13:16 +0200 Subject: [PATCH 14/15] Remove redundant check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Cristian Pallarés --- src/plugins/setup.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plugins/setup.ts b/src/plugins/setup.ts index b1598a9..4b2f7ca 100644 --- a/src/plugins/setup.ts +++ b/src/plugins/setup.ts @@ -174,7 +174,6 @@ export default createPlugin( // then there will be no license info to be reported by `localstack license info`. // Also, an expired license could be cached. // Activating the license pre-emptively to know its state during the setup process. - await activateLicense(outputChannel); const licenseIsValid = await minDelay( activateLicense(outputChannel).then(() => checkIsLicenseValid(outputChannel), From 338592543795fa03313ca3c7fffe278a52236431 Mon Sep 17 00:00:00 2001 From: Misha Tiurin Date: Thu, 4 Sep 2025 16:14:58 +0200 Subject: [PATCH 15/15] Remove confirmation in progress Not really needed, we don't have it for other steps and less transitions are easier on eyes. --- src/plugins/setup.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/plugins/setup.ts b/src/plugins/setup.ts index 4b2f7ca..6557eec 100644 --- a/src/plugins/setup.ts +++ b/src/plugins/setup.ts @@ -179,11 +179,7 @@ export default createPlugin( checkIsLicenseValid(outputChannel), ), ); - if (licenseIsValid) { - progress.report({ - message: "License verified successfully...", - }); - } else { + if (!licenseIsValid) { progress.report({ message: "License is not valid or not assigned. Open License settings page to activate it.",