@uipath/authz-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 +142 -30
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -2206,22 +2206,12 @@ var resolveConfigAsync = async ({
|
|
|
2206
2206
|
baseUrl = DEFAULT_BASE_URL;
|
|
2207
2207
|
}
|
|
2208
2208
|
baseUrl = normalizeAndValidateBaseUrl(baseUrl);
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
clientId = fileAuth.clientId;
|
|
2212
|
-
}
|
|
2213
|
-
if (!clientId) {
|
|
2214
|
-
clientId = DEFAULT_CLIENT_ID;
|
|
2215
|
-
}
|
|
2216
|
-
let clientSecret = customClientSecret;
|
|
2217
|
-
if (!clientSecret && fileAuth.clientSecret) {
|
|
2218
|
-
clientSecret = fileAuth.clientSecret;
|
|
2219
|
-
}
|
|
2220
|
-
const isExternalAppAuth = clientId !== DEFAULT_CLIENT_ID && (Boolean(clientSecret) || Boolean(customClientAssertion));
|
|
2209
|
+
const clientId = customClientId || DEFAULT_CLIENT_ID;
|
|
2210
|
+
const isExternalAppAuth = clientId !== DEFAULT_CLIENT_ID && (Boolean(customClientSecret) || Boolean(customClientAssertion));
|
|
2221
2211
|
const scopes = resolveScopes(isExternalAppAuth, customScopes, fileAuth.scopes);
|
|
2222
2212
|
return {
|
|
2223
2213
|
clientId,
|
|
2224
|
-
clientSecret,
|
|
2214
|
+
clientSecret: customClientSecret,
|
|
2225
2215
|
scopes,
|
|
2226
2216
|
baseUrl,
|
|
2227
2217
|
authorizationEndpoint: `${baseUrl}/identity_/connect/authorize`,
|
|
@@ -2414,6 +2404,16 @@ class NodeFileSystem {
|
|
|
2414
2404
|
async rename(oldPath, newPath) {
|
|
2415
2405
|
await fs.rename(oldPath, newPath);
|
|
2416
2406
|
}
|
|
2407
|
+
async isSymbolicLink(filePath) {
|
|
2408
|
+
try {
|
|
2409
|
+
return (await fs.lstat(filePath)).isSymbolicLink();
|
|
2410
|
+
} catch (error) {
|
|
2411
|
+
if (this.isEnoent(error) || this.hasErrnoCode(error, "ENOTDIR")) {
|
|
2412
|
+
return false;
|
|
2413
|
+
}
|
|
2414
|
+
throw error;
|
|
2415
|
+
}
|
|
2416
|
+
}
|
|
2417
2417
|
async realpath(filePath) {
|
|
2418
2418
|
try {
|
|
2419
2419
|
return await fs.realpath(filePath);
|
|
@@ -2625,6 +2625,16 @@ var resolveIdentityType = (claims, authFlow, email) => {
|
|
|
2625
2625
|
}
|
|
2626
2626
|
return;
|
|
2627
2627
|
};
|
|
2628
|
+
var resolveApplicationSubtype = (claims, authFlow) => {
|
|
2629
|
+
switch (asString(claims?.sub_type)) {
|
|
2630
|
+
case "service.external":
|
|
2631
|
+
return "External";
|
|
2632
|
+
case "service.internal":
|
|
2633
|
+
return "Internal";
|
|
2634
|
+
default:
|
|
2635
|
+
return authFlow === "client_credentials" || authFlow === "federated_credentials" ? "External" : undefined;
|
|
2636
|
+
}
|
|
2637
|
+
};
|
|
2628
2638
|
var looksLikeEmail = (value) => value?.includes("@") ?? false;
|
|
2629
2639
|
var pickEmail = (claims) => {
|
|
2630
2640
|
for (const candidate of [claims?.email, claims?.preferred_username]) {
|
|
@@ -2666,6 +2676,12 @@ var resolveSessionIdentity = (accessToken, authFlow) => {
|
|
|
2666
2676
|
const clientId = asString(claims?.client_id);
|
|
2667
2677
|
if (clientId)
|
|
2668
2678
|
identity.clientId = clientId;
|
|
2679
|
+
const subType = asString(claims?.sub_type);
|
|
2680
|
+
if (subType)
|
|
2681
|
+
identity.subType = subType;
|
|
2682
|
+
const applicationSubtype = resolveApplicationSubtype(claims, authFlow);
|
|
2683
|
+
if (applicationSubtype)
|
|
2684
|
+
identity.applicationSubtype = applicationSubtype;
|
|
2669
2685
|
return identity;
|
|
2670
2686
|
};
|
|
2671
2687
|
var readTokenScopes = (accessToken) => accessToken ? pickScopes(decodeClaims(accessToken)) : undefined;
|
|
@@ -2958,6 +2974,40 @@ var tryRobotClientFallback = async (options = {}) => {
|
|
|
2958
2974
|
}
|
|
2959
2975
|
};
|
|
2960
2976
|
|
|
2977
|
+
// ../../auth/src/tenantSelection.ts
|
|
2978
|
+
var LOGIN_STATUS_HINT = "Run 'uip login status' to see the organization the CLI is signed in to.";
|
|
2979
|
+
var organizationHint = (organizationId) => `The request used '${organizationId}' as the organization. ${LOGIN_STATUS_HINT}`;
|
|
2980
|
+
var IDENTIFIER_STATUSES = new Set([400, 403, 404]);
|
|
2981
|
+
var describeNonJsonResponse = (organizationId, response, parseError) => {
|
|
2982
|
+
if (response.redirected) {
|
|
2983
|
+
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}`;
|
|
2984
|
+
}
|
|
2985
|
+
const contentType = response.headers.get("content-type") ?? "unknown";
|
|
2986
|
+
return `The organization service returned a '${contentType}' response instead ` + `of JSON: ${parseError.message}. ${organizationHint(organizationId)}`;
|
|
2987
|
+
};
|
|
2988
|
+
var fetchTenantsAndOrganizations = async (baseUrl, accessToken, organizationId, signal) => {
|
|
2989
|
+
const url = `${baseUrl}/${organizationId}/portal_/api/filtering/leftnav/tenantsAndOrganizationInfo`;
|
|
2990
|
+
const response = await fetch(url, {
|
|
2991
|
+
headers: {
|
|
2992
|
+
Authorization: `Bearer ${accessToken}`
|
|
2993
|
+
},
|
|
2994
|
+
...signal ? { signal } : {}
|
|
2995
|
+
});
|
|
2996
|
+
if (!response.ok) {
|
|
2997
|
+
if (response.status === 401) {
|
|
2998
|
+
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);
|
|
2999
|
+
}
|
|
3000
|
+
const errorText = await response.text();
|
|
3001
|
+
const message = `Failed to get tenants and organizations: ${response.status} ${errorText}`;
|
|
3002
|
+
throw new Error(IDENTIFIER_STATUSES.has(response.status) ? `${message}. ${organizationHint(organizationId)}` : message);
|
|
3003
|
+
}
|
|
3004
|
+
const [parseError, data] = await catchError(response.json());
|
|
3005
|
+
if (parseError) {
|
|
3006
|
+
throw new Error(describeNonJsonResponse(organizationId, response, parseError));
|
|
3007
|
+
}
|
|
3008
|
+
return data;
|
|
3009
|
+
};
|
|
3010
|
+
|
|
2961
3011
|
// ../../auth/src/tokenRefresh.ts
|
|
2962
3012
|
var TOKEN_REFRESH_REAUTHENTICATE_MESSAGE = "Token refresh failed. Run 'uip login' to re-authenticate.";
|
|
2963
3013
|
|
|
@@ -3170,6 +3220,8 @@ var saveEnvFileAsync = async ({
|
|
|
3170
3220
|
};
|
|
3171
3221
|
|
|
3172
3222
|
// ../../auth/src/loginStatus.ts
|
|
3223
|
+
var defaultRobotTenantIdCache = new Map;
|
|
3224
|
+
var ROBOT_TENANT_LOOKUP_TIMEOUT_MS = 5000;
|
|
3173
3225
|
var getLoginStatusAsync = async (options = {}) => {
|
|
3174
3226
|
return getLoginStatusWithDeps(options);
|
|
3175
3227
|
};
|
|
@@ -3182,12 +3234,20 @@ var getLoginStatusWithDeps = async (options = {}, deps = {}) => {
|
|
|
3182
3234
|
refreshToken: refreshTokenFn = refreshAccessToken,
|
|
3183
3235
|
resolveConfig = resolveConfigAsync,
|
|
3184
3236
|
robotFallback = tryRobotClientFallback,
|
|
3237
|
+
fetchTenantsAndOrgs = fetchTenantsAndOrganizations,
|
|
3238
|
+
robotTenantIdCache = defaultRobotTenantIdCache,
|
|
3239
|
+
robotTenantLookupTimeoutMs = ROBOT_TENANT_LOOKUP_TIMEOUT_MS,
|
|
3185
3240
|
loadBreaker = loadRefreshBreaker,
|
|
3186
3241
|
saveBreaker = saveRefreshBreaker,
|
|
3187
3242
|
clearBreaker = clearRefreshBreaker
|
|
3188
3243
|
} = deps;
|
|
3244
|
+
const robotDeps = {
|
|
3245
|
+
fetchTenantsAndOrgs,
|
|
3246
|
+
cache: robotTenantIdCache,
|
|
3247
|
+
lookupTimeoutMs: robotTenantLookupTimeoutMs
|
|
3248
|
+
};
|
|
3189
3249
|
if (isRobotAuthEnforced()) {
|
|
3190
|
-
return resolveRobotEnforcedStatus(robotFallback);
|
|
3250
|
+
return resolveRobotEnforcedStatus(robotFallback, robotDeps);
|
|
3191
3251
|
}
|
|
3192
3252
|
if (isEnvAuthEnabled()) {
|
|
3193
3253
|
return readAuthFromEnv();
|
|
@@ -3205,7 +3265,7 @@ var getLoginStatusWithDeps = async (options = {}, deps = {}) => {
|
|
|
3205
3265
|
hint: `No credentials found for profile "${activeProfile}". Run 'uip login --profile ${activeProfile}' to authenticate this profile.`
|
|
3206
3266
|
};
|
|
3207
3267
|
}
|
|
3208
|
-
return resolveBorrowedRobotStatus(robotFallback);
|
|
3268
|
+
return resolveBorrowedRobotStatus(robotFallback, robotDeps);
|
|
3209
3269
|
}
|
|
3210
3270
|
const loaded = await loadFileCredentials(loadEnvFile, absolutePath);
|
|
3211
3271
|
if ("status" in loaded) {
|
|
@@ -3247,7 +3307,7 @@ var getLoginStatusWithDeps = async (options = {}, deps = {}) => {
|
|
|
3247
3307
|
}
|
|
3248
3308
|
return buildFileStatus(tokens, credentials, globalHint);
|
|
3249
3309
|
};
|
|
3250
|
-
async function resolveRobotEnforcedStatus(robotFallback) {
|
|
3310
|
+
async function resolveRobotEnforcedStatus(robotFallback, deps) {
|
|
3251
3311
|
if (isEnvAuthEnabled()) {
|
|
3252
3312
|
throw new EnvAuthConfigError(`${ENV_AUTH_ENABLE_VAR}=true and ${ENFORCE_ROBOT_AUTH_VAR}=true ` + `are mutually exclusive. Unset one of them and re-run.`);
|
|
3253
3313
|
}
|
|
@@ -3258,11 +3318,11 @@ async function resolveRobotEnforcedStatus(robotFallback) {
|
|
|
3258
3318
|
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.`
|
|
3259
3319
|
};
|
|
3260
3320
|
}
|
|
3261
|
-
return buildRobotStatus(robotCreds);
|
|
3321
|
+
return buildRobotStatus(robotCreds, deps);
|
|
3262
3322
|
}
|
|
3263
|
-
async function resolveBorrowedRobotStatus(robotFallback) {
|
|
3323
|
+
async function resolveBorrowedRobotStatus(robotFallback, deps) {
|
|
3264
3324
|
const robotCreds = await robotFallback();
|
|
3265
|
-
return robotCreds ? buildRobotStatus(robotCreds) : { loginStatus: "Not logged in" };
|
|
3325
|
+
return robotCreds ? buildRobotStatus(robotCreds, deps) : { loginStatus: "Not logged in" };
|
|
3266
3326
|
}
|
|
3267
3327
|
async function loadFileCredentials(loadEnvFile, absolutePath) {
|
|
3268
3328
|
let credentials;
|
|
@@ -3397,9 +3457,10 @@ function identityFields(accessToken, credentials) {
|
|
|
3397
3457
|
...scopes ? { scopes } : {}
|
|
3398
3458
|
};
|
|
3399
3459
|
}
|
|
3400
|
-
function buildRobotStatus(robotCreds) {
|
|
3460
|
+
async function buildRobotStatus(robotCreds, deps) {
|
|
3401
3461
|
const identity = resolveSessionIdentity(robotCreds.accessToken);
|
|
3402
3462
|
const scopes = readTokenScopes(robotCreds.accessToken);
|
|
3463
|
+
const tenant = robotCreds.tenantId ? { tenantId: robotCreds.tenantId } : await resolveRobotTenantId(robotCreds, deps);
|
|
3403
3464
|
return {
|
|
3404
3465
|
loginStatus: "Logged in",
|
|
3405
3466
|
accessToken: robotCreds.accessToken,
|
|
@@ -3407,14 +3468,62 @@ function buildRobotStatus(robotCreds) {
|
|
|
3407
3468
|
organizationName: robotCreds.organizationName,
|
|
3408
3469
|
organizationId: robotCreds.organizationId,
|
|
3409
3470
|
tenantName: robotCreds.tenantName,
|
|
3410
|
-
tenantId:
|
|
3471
|
+
tenantId: tenant.tenantId,
|
|
3411
3472
|
issuer: robotCreds.issuer,
|
|
3412
3473
|
expiration: getTokenExpiration(robotCreds.accessToken),
|
|
3413
3474
|
source: "robot" /* Robot */,
|
|
3475
|
+
...tenant.hint ? { hint: tenant.hint } : {},
|
|
3414
3476
|
...identity ? { identity } : {},
|
|
3415
3477
|
...scopes ? { scopes } : {}
|
|
3416
3478
|
};
|
|
3417
3479
|
}
|
|
3480
|
+
async function resolveRobotTenantId(robotCreds, deps) {
|
|
3481
|
+
const { baseUrl, accessToken, tenantName } = robotCreds;
|
|
3482
|
+
const organization = robotCreds.organizationName ?? robotCreds.organizationId;
|
|
3483
|
+
if (!tenantName || !organization) {
|
|
3484
|
+
return {};
|
|
3485
|
+
}
|
|
3486
|
+
const key = `${baseUrl}|${organization}|${tenantName}|${accessToken}`;
|
|
3487
|
+
let pending = deps.cache.get(key);
|
|
3488
|
+
if (!pending) {
|
|
3489
|
+
pending = catchError(lookupRobotTenantId({ baseUrl, accessToken, organization, tenantName }, deps)).then(([error, resolution]) => {
|
|
3490
|
+
const settled = error ? { hint: tenantLookupFailureHint(tenantName, error.message) } : resolution;
|
|
3491
|
+
if (!settled.tenantId) {
|
|
3492
|
+
deps.cache.delete(key);
|
|
3493
|
+
}
|
|
3494
|
+
return settled;
|
|
3495
|
+
});
|
|
3496
|
+
deps.cache.set(key, pending);
|
|
3497
|
+
}
|
|
3498
|
+
return pending;
|
|
3499
|
+
}
|
|
3500
|
+
async function lookupRobotTenantId(target, deps) {
|
|
3501
|
+
const { baseUrl, accessToken, organization, tenantName } = target;
|
|
3502
|
+
const [error, data] = await catchError(deps.fetchTenantsAndOrgs(baseUrl, accessToken, organization, AbortSignal.timeout(deps.lookupTimeoutMs)));
|
|
3503
|
+
if (error) {
|
|
3504
|
+
const reason = error.name === "TimeoutError" ? `the tenant list did not answer within ${deps.lookupTimeoutMs} ms.` : error.message;
|
|
3505
|
+
return { hint: tenantLookupFailureHint(tenantName, reason) };
|
|
3506
|
+
}
|
|
3507
|
+
const rows = data?.tenants;
|
|
3508
|
+
const tenants = Array.isArray(rows) ? rows.filter((tenant) => typeof tenant?.id === "string" && typeof tenant?.name === "string") : [];
|
|
3509
|
+
const wantedName = decodePathSegment(tenantName);
|
|
3510
|
+
const wanted = wantedName.toLowerCase();
|
|
3511
|
+
const match = tenants.find((tenant) => tenant.name === wantedName) ?? tenants.find((tenant) => tenant.name.toLowerCase() === wanted);
|
|
3512
|
+
if (!match) {
|
|
3513
|
+
const names = tenants.map((tenant) => tenant.name).join(", ");
|
|
3514
|
+
return {
|
|
3515
|
+
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.`
|
|
3516
|
+
};
|
|
3517
|
+
}
|
|
3518
|
+
return { tenantId: match.id };
|
|
3519
|
+
}
|
|
3520
|
+
function tenantLookupFailureHint(tenantName, reason) {
|
|
3521
|
+
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.`;
|
|
3522
|
+
}
|
|
3523
|
+
function decodePathSegment(segment) {
|
|
3524
|
+
const [error, decoded] = catchError(() => decodeURIComponent(segment));
|
|
3525
|
+
return error ? segment : decoded;
|
|
3526
|
+
}
|
|
3418
3527
|
var isFileNotFoundError = (error) => {
|
|
3419
3528
|
if (!(error instanceof Object))
|
|
3420
3529
|
return false;
|
|
@@ -3683,9 +3792,6 @@ var getAuthContext = async (options = {}) => {
|
|
|
3683
3792
|
identity: status.identity
|
|
3684
3793
|
};
|
|
3685
3794
|
};
|
|
3686
|
-
// ../../auth/src/tenantSelection.ts
|
|
3687
|
-
var IDENTIFIER_STATUSES = new Set([400, 403, 404]);
|
|
3688
|
-
|
|
3689
3795
|
// ../../auth/src/selectTenant.ts
|
|
3690
3796
|
var TENANT_SELECTION_REQUIRED_CODE = "TENANT_SELECTION_REQUIRED";
|
|
3691
3797
|
var INVALID_TENANT_CODE = "INVALID_TENANT";
|
|
@@ -3782,7 +3888,9 @@ var ErrorDimensions = {
|
|
|
3782
3888
|
Result: "Result",
|
|
3783
3889
|
ErrorCode: "ErrorCode",
|
|
3784
3890
|
Retry: "Retry",
|
|
3785
|
-
ErrorMessage: "ErrorMessage"
|
|
3891
|
+
ErrorMessage: "ErrorMessage",
|
|
3892
|
+
HttpStatus: "HttpStatus",
|
|
3893
|
+
UpstreamErrorCode: "UpstreamErrorCode"
|
|
3786
3894
|
};
|
|
3787
3895
|
var AuthDimensions = {
|
|
3788
3896
|
AuthenticationMethod: "AuthenticationMethod",
|
|
@@ -4206,7 +4314,7 @@ var package_default = {
|
|
|
4206
4314
|
name: "@uipath/authz-sdk",
|
|
4207
4315
|
author: "UiPath",
|
|
4208
4316
|
license: "SEE LICENSE IN LICENSE.txt",
|
|
4209
|
-
version: "1.
|
|
4317
|
+
version: "1.205.0",
|
|
4210
4318
|
description: "SDK for the UiPath Authorization Service API.",
|
|
4211
4319
|
repository: {
|
|
4212
4320
|
type: "git",
|
|
@@ -5759,7 +5867,7 @@ function setGlobalLogFilePath(path2) {
|
|
|
5759
5867
|
function getGlobalLogFilePath() {
|
|
5760
5868
|
return logFilePathSlot.get("");
|
|
5761
5869
|
}
|
|
5762
|
-
var DEFAULT_LOG_LEVEL =
|
|
5870
|
+
var DEFAULT_LOG_LEVEL = 2 /* WARN */;
|
|
5763
5871
|
|
|
5764
5872
|
class SimpleLogger {
|
|
5765
5873
|
__brand = "SimpleLogger";
|
|
@@ -6861,7 +6969,9 @@ var CLI_ERROR_CODES = [
|
|
|
6861
6969
|
"timeout",
|
|
6862
6970
|
"server_error",
|
|
6863
6971
|
"method_not_allowed",
|
|
6972
|
+
"not_supported",
|
|
6864
6973
|
"configuration_error",
|
|
6974
|
+
"execution_failed",
|
|
6865
6975
|
"unknown_error"
|
|
6866
6976
|
];
|
|
6867
6977
|
var RETRY_HINTS = [
|
|
@@ -7818,7 +7928,9 @@ var OutputFormatter;
|
|
|
7818
7928
|
[ErrorDimensions.Result]: data.Result,
|
|
7819
7929
|
[ErrorDimensions.ErrorCode]: data.ErrorCode,
|
|
7820
7930
|
[ErrorDimensions.Retry]: data.Retry,
|
|
7821
|
-
[ErrorDimensions.ErrorMessage]: data.Message
|
|
7931
|
+
[ErrorDimensions.ErrorMessage]: data.Message,
|
|
7932
|
+
[ErrorDimensions.HttpStatus]: data.Context?.httpStatus?.toString(),
|
|
7933
|
+
[ErrorDimensions.UpstreamErrorCode]: data.Context?.errorCode
|
|
7822
7934
|
});
|
|
7823
7935
|
}
|
|
7824
7936
|
logOutput(normalizeOutputKeys(envelope), getOutputFormat());
|
|
@@ -8913,7 +9025,7 @@ var package_default2 = {
|
|
|
8913
9025
|
name: "@uipath/identity-sdk",
|
|
8914
9026
|
author: "UiPath",
|
|
8915
9027
|
license: "SEE LICENSE IN LICENSE.txt",
|
|
8916
|
-
version: "1.
|
|
9028
|
+
version: "1.205.0",
|
|
8917
9029
|
repository: {
|
|
8918
9030
|
type: "git",
|
|
8919
9031
|
url: "https://github.com/UiPath/cli.git",
|
|
@@ -11369,4 +11481,4 @@ export {
|
|
|
11369
11481
|
registerCommands
|
|
11370
11482
|
};
|
|
11371
11483
|
|
|
11372
|
-
//# debugId=
|
|
11484
|
+
//# debugId=F2DB86481C2DAC6F64756E2164756E21
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@uipath/authz-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 the UiPath Authorization service. 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
|
}
|