@robinmordasiewicz/f5xc-xcsh 6.39.0 → 6.41.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +170 -28
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -45354,8 +45354,8 @@ function getLogoModeFromEnv(envPrefix) {
|
|
|
45354
45354
|
var CLI_NAME = "xcsh";
|
|
45355
45355
|
var CLI_FULL_NAME = "F5 Distributed Cloud Shell";
|
|
45356
45356
|
function getVersion() {
|
|
45357
|
-
if ("6.
|
|
45358
|
-
return "6.
|
|
45357
|
+
if ("6.41.0") {
|
|
45358
|
+
return "6.41.0";
|
|
45359
45359
|
}
|
|
45360
45360
|
if (process.env.XCSH_VERSION) {
|
|
45361
45361
|
return process.env.XCSH_VERSION;
|
|
@@ -45791,6 +45791,9 @@ var APIClient = class {
|
|
|
45791
45791
|
timeout;
|
|
45792
45792
|
debug;
|
|
45793
45793
|
retryConfig;
|
|
45794
|
+
// Token validation state
|
|
45795
|
+
_isValidated = false;
|
|
45796
|
+
_validationError = null;
|
|
45794
45797
|
constructor(config) {
|
|
45795
45798
|
this.serverUrl = config.serverUrl.replace(/\/+$/, "");
|
|
45796
45799
|
this.apiToken = config.apiToken ?? "";
|
|
@@ -45802,11 +45805,64 @@ var APIClient = class {
|
|
|
45802
45805
|
};
|
|
45803
45806
|
}
|
|
45804
45807
|
/**
|
|
45805
|
-
* Check if client has authentication configured
|
|
45808
|
+
* Check if client has authentication configured (token exists).
|
|
45809
|
+
* Note: This does NOT verify the token is valid. Use isValidated() for that.
|
|
45806
45810
|
*/
|
|
45807
45811
|
isAuthenticated() {
|
|
45808
45812
|
return this.apiToken !== "";
|
|
45809
45813
|
}
|
|
45814
|
+
/**
|
|
45815
|
+
* Validate the API token by making a lightweight API call.
|
|
45816
|
+
* Returns true if token is valid, false otherwise.
|
|
45817
|
+
*/
|
|
45818
|
+
async validateToken() {
|
|
45819
|
+
if (!this.apiToken) {
|
|
45820
|
+
this._isValidated = false;
|
|
45821
|
+
this._validationError = "No API token configured";
|
|
45822
|
+
return { valid: false, error: this._validationError };
|
|
45823
|
+
}
|
|
45824
|
+
try {
|
|
45825
|
+
await this.get("/api/web/namespaces");
|
|
45826
|
+
this._isValidated = true;
|
|
45827
|
+
this._validationError = null;
|
|
45828
|
+
return { valid: true };
|
|
45829
|
+
} catch (error) {
|
|
45830
|
+
this._isValidated = false;
|
|
45831
|
+
if (error instanceof APIError) {
|
|
45832
|
+
if (error.statusCode === 401) {
|
|
45833
|
+
this._validationError = "Invalid or expired API token";
|
|
45834
|
+
} else if (error.statusCode === 403) {
|
|
45835
|
+
this._validationError = "Token lacks required permissions";
|
|
45836
|
+
} else if (error.statusCode === 0) {
|
|
45837
|
+
this._validationError = "Network error - could not reach server";
|
|
45838
|
+
} else {
|
|
45839
|
+
this._validationError = `Validation failed: HTTP ${error.statusCode}`;
|
|
45840
|
+
}
|
|
45841
|
+
} else {
|
|
45842
|
+
this._validationError = "Validation failed: Unknown error";
|
|
45843
|
+
}
|
|
45844
|
+
return { valid: false, error: this._validationError };
|
|
45845
|
+
}
|
|
45846
|
+
}
|
|
45847
|
+
/**
|
|
45848
|
+
* Check if client has a validated (verified working) token
|
|
45849
|
+
*/
|
|
45850
|
+
isValidated() {
|
|
45851
|
+
return this._isValidated;
|
|
45852
|
+
}
|
|
45853
|
+
/**
|
|
45854
|
+
* Get the validation error message, if any
|
|
45855
|
+
*/
|
|
45856
|
+
getValidationError() {
|
|
45857
|
+
return this._validationError;
|
|
45858
|
+
}
|
|
45859
|
+
/**
|
|
45860
|
+
* Clear validation state (called on profile switch)
|
|
45861
|
+
*/
|
|
45862
|
+
clearValidationCache() {
|
|
45863
|
+
this._isValidated = false;
|
|
45864
|
+
this._validationError = null;
|
|
45865
|
+
}
|
|
45810
45866
|
/**
|
|
45811
45867
|
* Get the server URL
|
|
45812
45868
|
*/
|
|
@@ -46766,6 +46822,9 @@ var REPLSession = class {
|
|
|
46766
46822
|
_activeProfileName = null;
|
|
46767
46823
|
_namespaceCache = [];
|
|
46768
46824
|
_namespaceCacheTime = 0;
|
|
46825
|
+
// Token validation state
|
|
46826
|
+
_tokenValidated = false;
|
|
46827
|
+
_validationError = null;
|
|
46769
46828
|
constructor(config = {}) {
|
|
46770
46829
|
this._namespace = config.namespace ?? this.getDefaultNamespace();
|
|
46771
46830
|
this._contextPath = new ContextPath();
|
|
@@ -46801,7 +46860,12 @@ var REPLSession = class {
|
|
|
46801
46860
|
}
|
|
46802
46861
|
await this.loadActiveProfile();
|
|
46803
46862
|
if (this._apiClient?.isAuthenticated()) {
|
|
46804
|
-
await this.
|
|
46863
|
+
const result = await this._apiClient.validateToken();
|
|
46864
|
+
this._tokenValidated = result.valid;
|
|
46865
|
+
this._validationError = result.error ?? null;
|
|
46866
|
+
if (result.valid) {
|
|
46867
|
+
await this.fetchUserInfo();
|
|
46868
|
+
}
|
|
46805
46869
|
}
|
|
46806
46870
|
}
|
|
46807
46871
|
/**
|
|
@@ -46963,6 +47027,18 @@ var REPLSession = class {
|
|
|
46963
47027
|
isAuthenticated() {
|
|
46964
47028
|
return this._apiClient?.isAuthenticated() ?? false;
|
|
46965
47029
|
}
|
|
47030
|
+
/**
|
|
47031
|
+
* Check if the token has been validated (verified working)
|
|
47032
|
+
*/
|
|
47033
|
+
isTokenValidated() {
|
|
47034
|
+
return this._tokenValidated;
|
|
47035
|
+
}
|
|
47036
|
+
/**
|
|
47037
|
+
* Get the token validation error, if any
|
|
47038
|
+
*/
|
|
47039
|
+
getValidationError() {
|
|
47040
|
+
return this._validationError;
|
|
47041
|
+
}
|
|
46966
47042
|
/**
|
|
46967
47043
|
* Get the API client
|
|
46968
47044
|
*/
|
|
@@ -47018,6 +47094,8 @@ var REPLSession = class {
|
|
|
47018
47094
|
return false;
|
|
47019
47095
|
}
|
|
47020
47096
|
this.clearNamespaceCache();
|
|
47097
|
+
this._tokenValidated = false;
|
|
47098
|
+
this._validationError = null;
|
|
47021
47099
|
this._activeProfileName = profileName;
|
|
47022
47100
|
this._activeProfile = profile;
|
|
47023
47101
|
if (profile.apiUrl) {
|
|
@@ -47036,6 +47114,11 @@ var REPLSession = class {
|
|
|
47036
47114
|
apiToken: this._apiToken,
|
|
47037
47115
|
debug: this._debug
|
|
47038
47116
|
});
|
|
47117
|
+
if (this._apiClient.isAuthenticated()) {
|
|
47118
|
+
const validationResult = await this._apiClient.validateToken();
|
|
47119
|
+
this._tokenValidated = validationResult.valid;
|
|
47120
|
+
this._validationError = validationResult.error ?? null;
|
|
47121
|
+
}
|
|
47039
47122
|
} else {
|
|
47040
47123
|
this._apiClient = null;
|
|
47041
47124
|
}
|
|
@@ -48390,6 +48473,18 @@ function extractTenantFromUrl(url) {
|
|
|
48390
48473
|
return "unknown";
|
|
48391
48474
|
}
|
|
48392
48475
|
}
|
|
48476
|
+
function getAuthStatusValue(info, colorStatus) {
|
|
48477
|
+
if (!info.hasToken) {
|
|
48478
|
+
return colorStatus("\u2717 No token", false);
|
|
48479
|
+
}
|
|
48480
|
+
if (info.isValidated) {
|
|
48481
|
+
return colorStatus("\u2713 Authenticated", true);
|
|
48482
|
+
}
|
|
48483
|
+
if (info.validationError) {
|
|
48484
|
+
return colorStatus(`\u2717 ${info.validationError}`, false);
|
|
48485
|
+
}
|
|
48486
|
+
return colorStatus("\u26A0 Token not verified", false);
|
|
48487
|
+
}
|
|
48393
48488
|
function formatConnectionTable(info, noColor = false) {
|
|
48394
48489
|
const useColors = shouldUseColors(void 0, noColor);
|
|
48395
48490
|
const box = useColors ? UNICODE_BOX2 : ASCII_BOX2;
|
|
@@ -48404,7 +48499,7 @@ function formatConnectionTable(info, noColor = false) {
|
|
|
48404
48499
|
{ label: "API URL", value: info.apiUrl },
|
|
48405
48500
|
{
|
|
48406
48501
|
label: "Auth",
|
|
48407
|
-
value: info
|
|
48502
|
+
value: getAuthStatusValue(info, colorStatus)
|
|
48408
48503
|
},
|
|
48409
48504
|
{ label: "Namespace", value: info.namespace || "default" },
|
|
48410
48505
|
{
|
|
@@ -48445,8 +48540,8 @@ function formatConnectionTable(info, noColor = false) {
|
|
|
48445
48540
|
function stripAnsi2(str) {
|
|
48446
48541
|
return str.replace(/\x1b\[[0-9;]*m/g, "");
|
|
48447
48542
|
}
|
|
48448
|
-
function buildConnectionInfo(profileName, apiUrl, hasToken, namespace, isConnected) {
|
|
48449
|
-
|
|
48543
|
+
function buildConnectionInfo(profileName, apiUrl, hasToken, namespace, isConnected, isValidated, validationError) {
|
|
48544
|
+
const info = {
|
|
48450
48545
|
profileName,
|
|
48451
48546
|
tenant: extractTenantFromUrl(apiUrl),
|
|
48452
48547
|
apiUrl,
|
|
@@ -48454,6 +48549,13 @@ function buildConnectionInfo(profileName, apiUrl, hasToken, namespace, isConnect
|
|
|
48454
48549
|
namespace,
|
|
48455
48550
|
isConnected
|
|
48456
48551
|
};
|
|
48552
|
+
if (isValidated !== void 0) {
|
|
48553
|
+
info.isValidated = isValidated;
|
|
48554
|
+
}
|
|
48555
|
+
if (validationError) {
|
|
48556
|
+
info.validationError = validationError;
|
|
48557
|
+
}
|
|
48558
|
+
return info;
|
|
48457
48559
|
}
|
|
48458
48560
|
|
|
48459
48561
|
// src/domains/login/profile/create.ts
|
|
@@ -48568,7 +48670,9 @@ var useCommand = {
|
|
|
48568
48670
|
profile?.apiUrl || "",
|
|
48569
48671
|
!!profile?.apiToken,
|
|
48570
48672
|
profile?.defaultNamespace || session.getNamespace(),
|
|
48571
|
-
session.isAuthenticated()
|
|
48673
|
+
session.isAuthenticated(),
|
|
48674
|
+
session.isTokenValidated(),
|
|
48675
|
+
session.getValidationError() ?? void 0
|
|
48572
48676
|
);
|
|
48573
48677
|
const tableLines = formatConnectionTable(connectionInfo);
|
|
48574
48678
|
return successResult(
|
|
@@ -48920,6 +49024,21 @@ function colorizeLogoLine(line) {
|
|
|
48920
49024
|
}
|
|
48921
49025
|
return result;
|
|
48922
49026
|
}
|
|
49027
|
+
function wrapText4(text, maxWidth) {
|
|
49028
|
+
const words = text.split(" ");
|
|
49029
|
+
const lines = [];
|
|
49030
|
+
let currentLine = "";
|
|
49031
|
+
for (const word of words) {
|
|
49032
|
+
if (currentLine.length + word.length + 1 <= maxWidth) {
|
|
49033
|
+
currentLine += (currentLine ? " " : "") + word;
|
|
49034
|
+
} else {
|
|
49035
|
+
if (currentLine) lines.push(currentLine);
|
|
49036
|
+
currentLine = word;
|
|
49037
|
+
}
|
|
49038
|
+
}
|
|
49039
|
+
if (currentLine) lines.push(currentLine);
|
|
49040
|
+
return lines;
|
|
49041
|
+
}
|
|
48923
49042
|
function printImageBanner(imageSeq, imageHeight, imageWidth) {
|
|
48924
49043
|
const BOX = {
|
|
48925
49044
|
topLeft: "\u256D",
|
|
@@ -48933,11 +49052,7 @@ function printImageBanner(imageSeq, imageHeight, imageWidth) {
|
|
|
48933
49052
|
const INNER_WIDTH = TOTAL_WIDTH - 2;
|
|
48934
49053
|
const IMAGE_COL_WIDTH = 1 + imageWidth + 1;
|
|
48935
49054
|
const TEXT_COL_WIDTH = INNER_WIDTH - IMAGE_COL_WIDTH;
|
|
48936
|
-
const HELP_LINES =
|
|
48937
|
-
"Type 'help' for commands",
|
|
48938
|
-
"Run 'namespace <ns>' to set",
|
|
48939
|
-
"Press Ctrl+C twice to exit"
|
|
48940
|
-
];
|
|
49055
|
+
const HELP_LINES = wrapText4(CLI_DESCRIPTION_MEDIUM, TEXT_COL_WIDTH - 2);
|
|
48941
49056
|
const helpStartRow = Math.floor((imageHeight - HELP_LINES.length) / 2);
|
|
48942
49057
|
const title = ` ${CLI_FULL_NAME} v${CLI_VERSION} `;
|
|
48943
49058
|
const leftDashes = 3;
|
|
@@ -48987,11 +49102,8 @@ function printAsciiBanner() {
|
|
|
48987
49102
|
const logoWidth = Math.max(...logoLines.map((l) => [...l].length));
|
|
48988
49103
|
const TOTAL_WIDTH = Math.max(80, logoWidth + 4);
|
|
48989
49104
|
const INNER_WIDTH = TOTAL_WIDTH - 2;
|
|
48990
|
-
const
|
|
48991
|
-
|
|
48992
|
-
"Run 'namespace <ns>' to set",
|
|
48993
|
-
"Press Ctrl+C twice to exit"
|
|
48994
|
-
];
|
|
49105
|
+
const helpColumnWidth = INNER_WIDTH - logoWidth - 1;
|
|
49106
|
+
const HELP_LINES = wrapText4(CLI_DESCRIPTION_MEDIUM, helpColumnWidth - 2);
|
|
48995
49107
|
const HELP_START_ROW = 8;
|
|
48996
49108
|
const title = ` ${CLI_FULL_NAME} v${CLI_VERSION} `;
|
|
48997
49109
|
const leftDashes = 3;
|
|
@@ -49008,7 +49120,6 @@ function printAsciiBanner() {
|
|
|
49008
49120
|
const helpText = helpIndex >= 0 && helpIndex < HELP_LINES.length ? HELP_LINES[helpIndex] ?? "" : "";
|
|
49009
49121
|
const paddedLogo = logoLine.padEnd(logoWidth);
|
|
49010
49122
|
const coloredLogo = colorizeLogoLine(paddedLogo);
|
|
49011
|
-
const helpColumnWidth = INNER_WIDTH - logoWidth - 1;
|
|
49012
49123
|
const paddedHelp = helpText.padEnd(helpColumnWidth);
|
|
49013
49124
|
output.push(
|
|
49014
49125
|
colorRed(BOX.vertical) + coloredLogo + " " + colorBoldWhite(paddedHelp) + colorRed(BOX.vertical)
|
|
@@ -49039,11 +49150,7 @@ function getBannerLines(logoMode, useImage) {
|
|
|
49039
49150
|
const logoWidth = Math.max(...logoLines.map((l) => [...l].length));
|
|
49040
49151
|
const TOTAL_WIDTH = Math.max(80, logoWidth + 4);
|
|
49041
49152
|
const INNER_WIDTH = TOTAL_WIDTH - 2;
|
|
49042
|
-
const
|
|
49043
|
-
"Type 'help' for commands",
|
|
49044
|
-
"Run 'namespace <ns>' to set",
|
|
49045
|
-
"Press Ctrl+C twice to exit"
|
|
49046
|
-
];
|
|
49153
|
+
const helpColumnWidth = INNER_WIDTH - logoWidth - 1;
|
|
49047
49154
|
const title = ` ${CLI_FULL_NAME} v${CLI_VERSION} `;
|
|
49048
49155
|
const leftDashes = 3;
|
|
49049
49156
|
const rightDashes = TOTAL_WIDTH - 1 - leftDashes - title.length - 1;
|
|
@@ -49064,8 +49171,12 @@ function getBannerLines(logoMode, useImage) {
|
|
|
49064
49171
|
const imageWidth = F5_LOGO_DISPLAY_WIDTH;
|
|
49065
49172
|
const IMAGE_COL_WIDTH = 1 + imageWidth + 1;
|
|
49066
49173
|
const TEXT_COL_WIDTH = INNER_WIDTH - IMAGE_COL_WIDTH;
|
|
49174
|
+
const HELP_LINES2 = wrapText4(
|
|
49175
|
+
CLI_DESCRIPTION_MEDIUM,
|
|
49176
|
+
TEXT_COL_WIDTH - 2
|
|
49177
|
+
);
|
|
49067
49178
|
const helpStartRow = Math.floor(
|
|
49068
|
-
(imageHeight -
|
|
49179
|
+
(imageHeight - HELP_LINES2.length) / 2
|
|
49069
49180
|
);
|
|
49070
49181
|
let bannerStr = "";
|
|
49071
49182
|
bannerStr += "\n";
|
|
@@ -49075,7 +49186,7 @@ function getBannerLines(logoMode, useImage) {
|
|
|
49075
49186
|
bannerStr += colorRed(BOX.vertical) + " ".repeat(INNER_WIDTH) + colorRed(BOX.vertical) + "\n";
|
|
49076
49187
|
for (let row = 0; row < imageHeight; row++) {
|
|
49077
49188
|
const helpIndex = row - helpStartRow;
|
|
49078
|
-
const helpText = helpIndex >= 0 && helpIndex <
|
|
49189
|
+
const helpText = helpIndex >= 0 && helpIndex < HELP_LINES2.length ? HELP_LINES2[helpIndex] ?? "" : "";
|
|
49079
49190
|
const imageSpace = " ".repeat(IMAGE_COL_WIDTH);
|
|
49080
49191
|
const paddedHelp = helpText.padEnd(TEXT_COL_WIDTH);
|
|
49081
49192
|
bannerStr += colorRed(BOX.vertical) + imageSpace + colorBoldWhite(paddedHelp) + colorRed(BOX.vertical) + "\n";
|
|
@@ -49094,6 +49205,7 @@ function getBannerLines(logoMode, useImage) {
|
|
|
49094
49205
|
}
|
|
49095
49206
|
}
|
|
49096
49207
|
const HELP_START_ROW = 8;
|
|
49208
|
+
const HELP_LINES = wrapText4(CLI_DESCRIPTION_MEDIUM, helpColumnWidth - 2);
|
|
49097
49209
|
output.push("");
|
|
49098
49210
|
output.push(
|
|
49099
49211
|
colorRed(BOX.topLeft + BOX.horizontal.repeat(leftDashes)) + colorBoldWhite(title) + colorRed(
|
|
@@ -49106,7 +49218,6 @@ function getBannerLines(logoMode, useImage) {
|
|
|
49106
49218
|
const helpText = helpIndex >= 0 && helpIndex < HELP_LINES.length ? HELP_LINES[helpIndex] ?? "" : "";
|
|
49107
49219
|
const paddedLogo = logoLine.padEnd(logoWidth);
|
|
49108
49220
|
const coloredLogo = colorizeLogoLine(paddedLogo);
|
|
49109
|
-
const helpColumnWidth = INNER_WIDTH - logoWidth - 1;
|
|
49110
49221
|
const paddedHelp = helpText.padEnd(helpColumnWidth);
|
|
49111
49222
|
output.push(
|
|
49112
49223
|
colorRed(BOX.vertical) + coloredLogo + " " + colorBoldWhite(paddedHelp) + colorRed(BOX.vertical)
|
|
@@ -49260,6 +49371,14 @@ async function getWhoamiInfo(session, _options = {}) {
|
|
|
49260
49371
|
namespace: session.getNamespace(),
|
|
49261
49372
|
isAuthenticated: session.isAuthenticated()
|
|
49262
49373
|
};
|
|
49374
|
+
const isValidated = session.isTokenValidated();
|
|
49375
|
+
const validationError = session.getValidationError();
|
|
49376
|
+
if (isValidated !== void 0) {
|
|
49377
|
+
info.isValidated = isValidated;
|
|
49378
|
+
}
|
|
49379
|
+
if (validationError) {
|
|
49380
|
+
info.validationError = validationError;
|
|
49381
|
+
}
|
|
49263
49382
|
if (!info.isAuthenticated) {
|
|
49264
49383
|
return info;
|
|
49265
49384
|
}
|
|
@@ -49298,6 +49417,18 @@ function formatWhoamiJson(info) {
|
|
|
49298
49417
|
output.isAuthenticated = info.isAuthenticated;
|
|
49299
49418
|
return [JSON.stringify(output, null, 2)];
|
|
49300
49419
|
}
|
|
49420
|
+
function getAuthStatusDisplay(info) {
|
|
49421
|
+
if (!info.isAuthenticated) {
|
|
49422
|
+
return "Not authenticated";
|
|
49423
|
+
}
|
|
49424
|
+
if (info.isValidated) {
|
|
49425
|
+
return "\u2713 Authenticated";
|
|
49426
|
+
}
|
|
49427
|
+
if (info.validationError) {
|
|
49428
|
+
return `\u2717 ${info.validationError}`;
|
|
49429
|
+
}
|
|
49430
|
+
return "\u26A0 Token not verified";
|
|
49431
|
+
}
|
|
49301
49432
|
function formatWhoamiBox(info) {
|
|
49302
49433
|
const lines = [];
|
|
49303
49434
|
const red = colors.red;
|
|
@@ -49323,7 +49454,7 @@ function formatWhoamiBox(info) {
|
|
|
49323
49454
|
contentLines.push({ label: "Server", value: info.serverUrl });
|
|
49324
49455
|
contentLines.push({
|
|
49325
49456
|
label: "Auth",
|
|
49326
|
-
value: info
|
|
49457
|
+
value: getAuthStatusDisplay(info)
|
|
49327
49458
|
});
|
|
49328
49459
|
const maxLabelWidth = Math.max(...contentLines.map((c) => c.label.length));
|
|
49329
49460
|
const formattedContent = contentLines.map((c) => {
|
|
@@ -53055,6 +53186,12 @@ program2.name(CLI_NAME).description("F5 Distributed Cloud Shell - Interactive CL
|
|
|
53055
53186
|
await session.initialize();
|
|
53056
53187
|
process.stdout.write("\r\x1B[K");
|
|
53057
53188
|
renderBanner(cliLogoMode, "startup");
|
|
53189
|
+
if (session.isAuthenticated() && !session.isTokenValidated() && session.getValidationError()) {
|
|
53190
|
+
console.log("");
|
|
53191
|
+
console.log(
|
|
53192
|
+
`${colors.yellow}Warning: ${session.getValidationError()}${colors.reset}`
|
|
53193
|
+
);
|
|
53194
|
+
}
|
|
53058
53195
|
const profiles = await session.getProfileManager().list();
|
|
53059
53196
|
const envConfigured = process.env[`${ENV_PREFIX}_API_URL`] && process.env[`${ENV_PREFIX}_API_TOKEN`];
|
|
53060
53197
|
if (profiles.length === 0 && !envConfigured) {
|
|
@@ -53092,6 +53229,11 @@ program2.name(CLI_NAME).description("F5 Distributed Cloud Shell - Interactive CL
|
|
|
53092
53229
|
async function executeNonInteractive(args) {
|
|
53093
53230
|
const session = new REPLSession();
|
|
53094
53231
|
await session.initialize();
|
|
53232
|
+
if (session.isAuthenticated() && !session.isTokenValidated() && session.getValidationError()) {
|
|
53233
|
+
console.error(
|
|
53234
|
+
`${colors.yellow}Warning: ${session.getValidationError()}${colors.reset}`
|
|
53235
|
+
);
|
|
53236
|
+
}
|
|
53095
53237
|
const command = args.join(" ");
|
|
53096
53238
|
const result = await executeCommand(command, session);
|
|
53097
53239
|
result.output.forEach((line) => {
|