@uipath/identity-commands 1.204.0-preview.255 → 1.205.0-preview.256
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 +141 -29
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -2277,6 +2277,16 @@ class NodeFileSystem {
|
|
|
2277
2277
|
async rename(oldPath, newPath) {
|
|
2278
2278
|
await fs.rename(oldPath, newPath);
|
|
2279
2279
|
}
|
|
2280
|
+
async isSymbolicLink(filePath) {
|
|
2281
|
+
try {
|
|
2282
|
+
return (await fs.lstat(filePath)).isSymbolicLink();
|
|
2283
|
+
} catch (error) {
|
|
2284
|
+
if (this.isEnoent(error) || this.hasErrnoCode(error, "ENOTDIR")) {
|
|
2285
|
+
return false;
|
|
2286
|
+
}
|
|
2287
|
+
throw error;
|
|
2288
|
+
}
|
|
2289
|
+
}
|
|
2280
2290
|
async realpath(filePath) {
|
|
2281
2291
|
try {
|
|
2282
2292
|
return await fs.realpath(filePath);
|
|
@@ -3312,7 +3322,7 @@ function setGlobalLogFilePath(path2) {
|
|
|
3312
3322
|
function getGlobalLogFilePath() {
|
|
3313
3323
|
return logFilePathSlot.get("");
|
|
3314
3324
|
}
|
|
3315
|
-
var DEFAULT_LOG_LEVEL =
|
|
3325
|
+
var DEFAULT_LOG_LEVEL = 2 /* WARN */;
|
|
3316
3326
|
|
|
3317
3327
|
class SimpleLogger {
|
|
3318
3328
|
__brand = "SimpleLogger";
|
|
@@ -3579,7 +3589,9 @@ var ErrorDimensions = {
|
|
|
3579
3589
|
Result: "Result",
|
|
3580
3590
|
ErrorCode: "ErrorCode",
|
|
3581
3591
|
Retry: "Retry",
|
|
3582
|
-
ErrorMessage: "ErrorMessage"
|
|
3592
|
+
ErrorMessage: "ErrorMessage",
|
|
3593
|
+
HttpStatus: "HttpStatus",
|
|
3594
|
+
UpstreamErrorCode: "UpstreamErrorCode"
|
|
3583
3595
|
};
|
|
3584
3596
|
var AuthDimensions = {
|
|
3585
3597
|
AuthenticationMethod: "AuthenticationMethod",
|
|
@@ -4567,7 +4579,9 @@ var CLI_ERROR_CODES = [
|
|
|
4567
4579
|
"timeout",
|
|
4568
4580
|
"server_error",
|
|
4569
4581
|
"method_not_allowed",
|
|
4582
|
+
"not_supported",
|
|
4570
4583
|
"configuration_error",
|
|
4584
|
+
"execution_failed",
|
|
4571
4585
|
"unknown_error"
|
|
4572
4586
|
];
|
|
4573
4587
|
var RETRY_HINTS = [
|
|
@@ -5524,7 +5538,9 @@ var OutputFormatter;
|
|
|
5524
5538
|
[ErrorDimensions.Result]: data.Result,
|
|
5525
5539
|
[ErrorDimensions.ErrorCode]: data.ErrorCode,
|
|
5526
5540
|
[ErrorDimensions.Retry]: data.Retry,
|
|
5527
|
-
[ErrorDimensions.ErrorMessage]: data.Message
|
|
5541
|
+
[ErrorDimensions.ErrorMessage]: data.Message,
|
|
5542
|
+
[ErrorDimensions.HttpStatus]: data.Context?.httpStatus?.toString(),
|
|
5543
|
+
[ErrorDimensions.UpstreamErrorCode]: data.Context?.errorCode
|
|
5528
5544
|
});
|
|
5529
5545
|
}
|
|
5530
5546
|
logOutput(normalizeOutputKeys(envelope), getOutputFormat());
|
|
@@ -6710,7 +6726,7 @@ var package_default = {
|
|
|
6710
6726
|
name: "@uipath/identity-sdk",
|
|
6711
6727
|
author: "UiPath",
|
|
6712
6728
|
license: "SEE LICENSE IN LICENSE.txt",
|
|
6713
|
-
version: "1.
|
|
6729
|
+
version: "1.205.0",
|
|
6714
6730
|
repository: {
|
|
6715
6731
|
type: "git",
|
|
6716
6732
|
url: "https://github.com/UiPath/cli.git",
|
|
@@ -9375,22 +9391,12 @@ var resolveConfigAsync = async ({
|
|
|
9375
9391
|
baseUrl = DEFAULT_BASE_URL;
|
|
9376
9392
|
}
|
|
9377
9393
|
baseUrl = normalizeAndValidateBaseUrl(baseUrl);
|
|
9378
|
-
|
|
9379
|
-
|
|
9380
|
-
clientId = fileAuth.clientId;
|
|
9381
|
-
}
|
|
9382
|
-
if (!clientId) {
|
|
9383
|
-
clientId = DEFAULT_CLIENT_ID;
|
|
9384
|
-
}
|
|
9385
|
-
let clientSecret = customClientSecret;
|
|
9386
|
-
if (!clientSecret && fileAuth.clientSecret) {
|
|
9387
|
-
clientSecret = fileAuth.clientSecret;
|
|
9388
|
-
}
|
|
9389
|
-
const isExternalAppAuth = clientId !== DEFAULT_CLIENT_ID && (Boolean(clientSecret) || Boolean(customClientAssertion));
|
|
9394
|
+
const clientId = customClientId || DEFAULT_CLIENT_ID;
|
|
9395
|
+
const isExternalAppAuth = clientId !== DEFAULT_CLIENT_ID && (Boolean(customClientSecret) || Boolean(customClientAssertion));
|
|
9390
9396
|
const scopes = resolveScopes(isExternalAppAuth, customScopes, fileAuth.scopes);
|
|
9391
9397
|
return {
|
|
9392
9398
|
clientId,
|
|
9393
|
-
clientSecret,
|
|
9399
|
+
clientSecret: customClientSecret,
|
|
9394
9400
|
scopes,
|
|
9395
9401
|
baseUrl,
|
|
9396
9402
|
authorizationEndpoint: `${baseUrl}/identity_/connect/authorize`,
|
|
@@ -9564,6 +9570,16 @@ var resolveIdentityType = (claims, authFlow, email) => {
|
|
|
9564
9570
|
}
|
|
9565
9571
|
return;
|
|
9566
9572
|
};
|
|
9573
|
+
var resolveApplicationSubtype = (claims, authFlow) => {
|
|
9574
|
+
switch (asString(claims?.sub_type)) {
|
|
9575
|
+
case "service.external":
|
|
9576
|
+
return "External";
|
|
9577
|
+
case "service.internal":
|
|
9578
|
+
return "Internal";
|
|
9579
|
+
default:
|
|
9580
|
+
return authFlow === "client_credentials" || authFlow === "federated_credentials" ? "External" : undefined;
|
|
9581
|
+
}
|
|
9582
|
+
};
|
|
9567
9583
|
var looksLikeEmail = (value) => value?.includes("@") ?? false;
|
|
9568
9584
|
var pickEmail = (claims) => {
|
|
9569
9585
|
for (const candidate of [claims?.email, claims?.preferred_username]) {
|
|
@@ -9605,6 +9621,12 @@ var resolveSessionIdentity = (accessToken, authFlow) => {
|
|
|
9605
9621
|
const clientId = asString(claims?.client_id);
|
|
9606
9622
|
if (clientId)
|
|
9607
9623
|
identity.clientId = clientId;
|
|
9624
|
+
const subType = asString(claims?.sub_type);
|
|
9625
|
+
if (subType)
|
|
9626
|
+
identity.subType = subType;
|
|
9627
|
+
const applicationSubtype = resolveApplicationSubtype(claims, authFlow);
|
|
9628
|
+
if (applicationSubtype)
|
|
9629
|
+
identity.applicationSubtype = applicationSubtype;
|
|
9608
9630
|
return identity;
|
|
9609
9631
|
};
|
|
9610
9632
|
var readTokenScopes = (accessToken) => accessToken ? pickScopes(decodeClaims(accessToken)) : undefined;
|
|
@@ -9897,6 +9919,40 @@ var tryRobotClientFallback = async (options = {}) => {
|
|
|
9897
9919
|
}
|
|
9898
9920
|
};
|
|
9899
9921
|
|
|
9922
|
+
// ../../auth/src/tenantSelection.ts
|
|
9923
|
+
var LOGIN_STATUS_HINT = "Run 'uip login status' to see the organization the CLI is signed in to.";
|
|
9924
|
+
var organizationHint = (organizationId) => `The request used '${organizationId}' as the organization. ${LOGIN_STATUS_HINT}`;
|
|
9925
|
+
var IDENTIFIER_STATUSES = new Set([400, 403, 404]);
|
|
9926
|
+
var describeNonJsonResponse = (organizationId, response, parseError) => {
|
|
9927
|
+
if (response.redirected) {
|
|
9928
|
+
return `Could not find organization '${organizationId}': the request was ` + `redirected to a sign-in page instead of the organization's tenant ` + `list. ${LOGIN_STATUS_HINT}`;
|
|
9929
|
+
}
|
|
9930
|
+
const contentType = response.headers.get("content-type") ?? "unknown";
|
|
9931
|
+
return `The organization service returned a '${contentType}' response instead ` + `of JSON: ${parseError.message}. ${organizationHint(organizationId)}`;
|
|
9932
|
+
};
|
|
9933
|
+
var fetchTenantsAndOrganizations = async (baseUrl, accessToken, organizationId, signal) => {
|
|
9934
|
+
const url = `${baseUrl}/${organizationId}/portal_/api/filtering/leftnav/tenantsAndOrganizationInfo`;
|
|
9935
|
+
const response = await fetch(url, {
|
|
9936
|
+
headers: {
|
|
9937
|
+
Authorization: `Bearer ${accessToken}`
|
|
9938
|
+
},
|
|
9939
|
+
...signal ? { signal } : {}
|
|
9940
|
+
});
|
|
9941
|
+
if (!response.ok) {
|
|
9942
|
+
if (response.status === 401) {
|
|
9943
|
+
throw new Error(`Unauthorized: the access token was rejected, it was not ` + `issued for organization '${organizationId}', or ` + `'${organizationId}' was not accepted as an organization ` + `URL segment in this environment. ` + LOGIN_STATUS_HINT);
|
|
9944
|
+
}
|
|
9945
|
+
const errorText = await response.text();
|
|
9946
|
+
const message = `Failed to get tenants and organizations: ${response.status} ${errorText}`;
|
|
9947
|
+
throw new Error(IDENTIFIER_STATUSES.has(response.status) ? `${message}. ${organizationHint(organizationId)}` : message);
|
|
9948
|
+
}
|
|
9949
|
+
const [parseError, data] = await catchError2(response.json());
|
|
9950
|
+
if (parseError) {
|
|
9951
|
+
throw new Error(describeNonJsonResponse(organizationId, response, parseError));
|
|
9952
|
+
}
|
|
9953
|
+
return data;
|
|
9954
|
+
};
|
|
9955
|
+
|
|
9900
9956
|
// ../../auth/src/tokenRefresh.ts
|
|
9901
9957
|
var TOKEN_REFRESH_REAUTHENTICATE_MESSAGE = "Token refresh failed. Run 'uip login' to re-authenticate.";
|
|
9902
9958
|
|
|
@@ -10109,6 +10165,8 @@ var saveEnvFileAsync = async ({
|
|
|
10109
10165
|
};
|
|
10110
10166
|
|
|
10111
10167
|
// ../../auth/src/loginStatus.ts
|
|
10168
|
+
var defaultRobotTenantIdCache = new Map;
|
|
10169
|
+
var ROBOT_TENANT_LOOKUP_TIMEOUT_MS = 5000;
|
|
10112
10170
|
var getLoginStatusAsync = async (options = {}) => {
|
|
10113
10171
|
return getLoginStatusWithDeps(options);
|
|
10114
10172
|
};
|
|
@@ -10121,12 +10179,20 @@ var getLoginStatusWithDeps = async (options = {}, deps = {}) => {
|
|
|
10121
10179
|
refreshToken: refreshTokenFn = refreshAccessToken,
|
|
10122
10180
|
resolveConfig = resolveConfigAsync,
|
|
10123
10181
|
robotFallback = tryRobotClientFallback,
|
|
10182
|
+
fetchTenantsAndOrgs = fetchTenantsAndOrganizations,
|
|
10183
|
+
robotTenantIdCache = defaultRobotTenantIdCache,
|
|
10184
|
+
robotTenantLookupTimeoutMs = ROBOT_TENANT_LOOKUP_TIMEOUT_MS,
|
|
10124
10185
|
loadBreaker = loadRefreshBreaker,
|
|
10125
10186
|
saveBreaker = saveRefreshBreaker,
|
|
10126
10187
|
clearBreaker = clearRefreshBreaker
|
|
10127
10188
|
} = deps;
|
|
10189
|
+
const robotDeps = {
|
|
10190
|
+
fetchTenantsAndOrgs,
|
|
10191
|
+
cache: robotTenantIdCache,
|
|
10192
|
+
lookupTimeoutMs: robotTenantLookupTimeoutMs
|
|
10193
|
+
};
|
|
10128
10194
|
if (isRobotAuthEnforced()) {
|
|
10129
|
-
return resolveRobotEnforcedStatus(robotFallback);
|
|
10195
|
+
return resolveRobotEnforcedStatus(robotFallback, robotDeps);
|
|
10130
10196
|
}
|
|
10131
10197
|
if (isEnvAuthEnabled()) {
|
|
10132
10198
|
return readAuthFromEnv();
|
|
@@ -10144,7 +10210,7 @@ var getLoginStatusWithDeps = async (options = {}, deps = {}) => {
|
|
|
10144
10210
|
hint: `No credentials found for profile "${activeProfile}". Run 'uip login --profile ${activeProfile}' to authenticate this profile.`
|
|
10145
10211
|
};
|
|
10146
10212
|
}
|
|
10147
|
-
return resolveBorrowedRobotStatus(robotFallback);
|
|
10213
|
+
return resolveBorrowedRobotStatus(robotFallback, robotDeps);
|
|
10148
10214
|
}
|
|
10149
10215
|
const loaded = await loadFileCredentials(loadEnvFile, absolutePath);
|
|
10150
10216
|
if ("status" in loaded) {
|
|
@@ -10186,7 +10252,7 @@ var getLoginStatusWithDeps = async (options = {}, deps = {}) => {
|
|
|
10186
10252
|
}
|
|
10187
10253
|
return buildFileStatus(tokens, credentials, globalHint);
|
|
10188
10254
|
};
|
|
10189
|
-
async function resolveRobotEnforcedStatus(robotFallback) {
|
|
10255
|
+
async function resolveRobotEnforcedStatus(robotFallback, deps) {
|
|
10190
10256
|
if (isEnvAuthEnabled()) {
|
|
10191
10257
|
throw new EnvAuthConfigError(`${ENV_AUTH_ENABLE_VAR}=true and ${ENFORCE_ROBOT_AUTH_VAR}=true ` + `are mutually exclusive. Unset one of them and re-run.`);
|
|
10192
10258
|
}
|
|
@@ -10197,11 +10263,11 @@ async function resolveRobotEnforcedStatus(robotFallback) {
|
|
|
10197
10263
|
hint: `${ENFORCE_ROBOT_AUTH_VAR}=true but the UiPath Robot ` + `session is unavailable. Start and sign in to the Assistant, ` + `or unset ${ENFORCE_ROBOT_AUTH_VAR} to fall back to file or ` + `env-var authentication.`
|
|
10198
10264
|
};
|
|
10199
10265
|
}
|
|
10200
|
-
return buildRobotStatus(robotCreds);
|
|
10266
|
+
return buildRobotStatus(robotCreds, deps);
|
|
10201
10267
|
}
|
|
10202
|
-
async function resolveBorrowedRobotStatus(robotFallback) {
|
|
10268
|
+
async function resolveBorrowedRobotStatus(robotFallback, deps) {
|
|
10203
10269
|
const robotCreds = await robotFallback();
|
|
10204
|
-
return robotCreds ? buildRobotStatus(robotCreds) : { loginStatus: "Not logged in" };
|
|
10270
|
+
return robotCreds ? buildRobotStatus(robotCreds, deps) : { loginStatus: "Not logged in" };
|
|
10205
10271
|
}
|
|
10206
10272
|
async function loadFileCredentials(loadEnvFile, absolutePath) {
|
|
10207
10273
|
let credentials;
|
|
@@ -10336,9 +10402,10 @@ function identityFields(accessToken, credentials) {
|
|
|
10336
10402
|
...scopes ? { scopes } : {}
|
|
10337
10403
|
};
|
|
10338
10404
|
}
|
|
10339
|
-
function buildRobotStatus(robotCreds) {
|
|
10405
|
+
async function buildRobotStatus(robotCreds, deps) {
|
|
10340
10406
|
const identity = resolveSessionIdentity(robotCreds.accessToken);
|
|
10341
10407
|
const scopes = readTokenScopes(robotCreds.accessToken);
|
|
10408
|
+
const tenant = robotCreds.tenantId ? { tenantId: robotCreds.tenantId } : await resolveRobotTenantId(robotCreds, deps);
|
|
10342
10409
|
return {
|
|
10343
10410
|
loginStatus: "Logged in",
|
|
10344
10411
|
accessToken: robotCreds.accessToken,
|
|
@@ -10346,14 +10413,62 @@ function buildRobotStatus(robotCreds) {
|
|
|
10346
10413
|
organizationName: robotCreds.organizationName,
|
|
10347
10414
|
organizationId: robotCreds.organizationId,
|
|
10348
10415
|
tenantName: robotCreds.tenantName,
|
|
10349
|
-
tenantId:
|
|
10416
|
+
tenantId: tenant.tenantId,
|
|
10350
10417
|
issuer: robotCreds.issuer,
|
|
10351
10418
|
expiration: getTokenExpiration(robotCreds.accessToken),
|
|
10352
10419
|
source: "robot" /* Robot */,
|
|
10420
|
+
...tenant.hint ? { hint: tenant.hint } : {},
|
|
10353
10421
|
...identity ? { identity } : {},
|
|
10354
10422
|
...scopes ? { scopes } : {}
|
|
10355
10423
|
};
|
|
10356
10424
|
}
|
|
10425
|
+
async function resolveRobotTenantId(robotCreds, deps) {
|
|
10426
|
+
const { baseUrl, accessToken, tenantName } = robotCreds;
|
|
10427
|
+
const organization = robotCreds.organizationName ?? robotCreds.organizationId;
|
|
10428
|
+
if (!tenantName || !organization) {
|
|
10429
|
+
return {};
|
|
10430
|
+
}
|
|
10431
|
+
const key = `${baseUrl}|${organization}|${tenantName}|${accessToken}`;
|
|
10432
|
+
let pending = deps.cache.get(key);
|
|
10433
|
+
if (!pending) {
|
|
10434
|
+
pending = catchError2(lookupRobotTenantId({ baseUrl, accessToken, organization, tenantName }, deps)).then(([error, resolution]) => {
|
|
10435
|
+
const settled = error ? { hint: tenantLookupFailureHint(tenantName, error.message) } : resolution;
|
|
10436
|
+
if (!settled.tenantId) {
|
|
10437
|
+
deps.cache.delete(key);
|
|
10438
|
+
}
|
|
10439
|
+
return settled;
|
|
10440
|
+
});
|
|
10441
|
+
deps.cache.set(key, pending);
|
|
10442
|
+
}
|
|
10443
|
+
return pending;
|
|
10444
|
+
}
|
|
10445
|
+
async function lookupRobotTenantId(target, deps) {
|
|
10446
|
+
const { baseUrl, accessToken, organization, tenantName } = target;
|
|
10447
|
+
const [error, data] = await catchError2(deps.fetchTenantsAndOrgs(baseUrl, accessToken, organization, AbortSignal.timeout(deps.lookupTimeoutMs)));
|
|
10448
|
+
if (error) {
|
|
10449
|
+
const reason = error.name === "TimeoutError" ? `the tenant list did not answer within ${deps.lookupTimeoutMs} ms.` : error.message;
|
|
10450
|
+
return { hint: tenantLookupFailureHint(tenantName, reason) };
|
|
10451
|
+
}
|
|
10452
|
+
const rows = data?.tenants;
|
|
10453
|
+
const tenants = Array.isArray(rows) ? rows.filter((tenant) => typeof tenant?.id === "string" && typeof tenant?.name === "string") : [];
|
|
10454
|
+
const wantedName = decodePathSegment(tenantName);
|
|
10455
|
+
const wanted = wantedName.toLowerCase();
|
|
10456
|
+
const match = tenants.find((tenant) => tenant.name === wantedName) ?? tenants.find((tenant) => tenant.name.toLowerCase() === wanted);
|
|
10457
|
+
if (!match) {
|
|
10458
|
+
const names = tenants.map((tenant) => tenant.name).join(", ");
|
|
10459
|
+
return {
|
|
10460
|
+
hint: `The Robot session targets tenant '${tenantName}', but ` + `organization '${organization}' lists no tenant of that name` + `${names ? ` (available: ${names})` : ""}. Commands that need ` + `the tenant id will fail until it can be resolved.`
|
|
10461
|
+
};
|
|
10462
|
+
}
|
|
10463
|
+
return { tenantId: match.id };
|
|
10464
|
+
}
|
|
10465
|
+
function tenantLookupFailureHint(tenantName, reason) {
|
|
10466
|
+
return `Could not resolve the id of tenant '${tenantName}' from the ` + `Robot session: ${reason} Commands that need the tenant id will ` + `fail until it can be resolved.`;
|
|
10467
|
+
}
|
|
10468
|
+
function decodePathSegment(segment) {
|
|
10469
|
+
const [error, decoded] = catchError2(() => decodeURIComponent(segment));
|
|
10470
|
+
return error ? segment : decoded;
|
|
10471
|
+
}
|
|
10357
10472
|
var isFileNotFoundError = (error) => {
|
|
10358
10473
|
if (!(error instanceof Object))
|
|
10359
10474
|
return false;
|
|
@@ -10622,9 +10737,6 @@ var getAuthContext = async (options = {}) => {
|
|
|
10622
10737
|
identity: status.identity
|
|
10623
10738
|
};
|
|
10624
10739
|
};
|
|
10625
|
-
// ../../auth/src/tenantSelection.ts
|
|
10626
|
-
var IDENTIFIER_STATUSES = new Set([400, 403, 404]);
|
|
10627
|
-
|
|
10628
10740
|
// ../../auth/src/selectTenant.ts
|
|
10629
10741
|
var TENANT_SELECTION_REQUIRED_CODE = "TENANT_SELECTION_REQUIRED";
|
|
10630
10742
|
var INVALID_TENANT_CODE = "INVALID_TENANT";
|
|
@@ -13008,4 +13120,4 @@ export {
|
|
|
13008
13120
|
registerCommands
|
|
13009
13121
|
};
|
|
13010
13122
|
|
|
13011
|
-
//# debugId=
|
|
13123
|
+
//# debugId=2614B63C0A818C8964756E2164756E21
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@uipath/identity-commands",
|
|
3
3
|
"author": "UiPath",
|
|
4
4
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
5
|
-
"version": "1.
|
|
5
|
+
"version": "1.205.0-preview.256",
|
|
6
6
|
"description": "Admin CLI commands for Identity Server users, groups, robot accounts, and external apps. Library composed by admin-tool, not a standalone CLI tool.",
|
|
7
7
|
"private": false,
|
|
8
8
|
"repository": {
|
|
@@ -26,5 +26,5 @@
|
|
|
26
26
|
"files": [
|
|
27
27
|
"dist"
|
|
28
28
|
],
|
|
29
|
-
"gitHead": "
|
|
29
|
+
"gitHead": "63740c6cbb7ff282fa9118cc16a148eb030b245f"
|
|
30
30
|
}
|