@uipath/auth 1.0.4 → 1.195.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/authContext.d.ts +17 -0
- package/dist/catch-error.d.ts +5 -0
- package/dist/clientCredentials.d.ts +9 -0
- package/dist/config.d.ts +73 -0
- package/dist/constants.d.ts +10 -0
- package/dist/envAuth.d.ts +75 -0
- package/dist/getBaseHtml.d.ts +7 -0
- package/dist/index.browser.d.ts +10 -0
- package/dist/index.browser.js +314 -115
- package/dist/index.d.ts +27 -0
- package/dist/index.js +528 -221
- package/dist/interactive.d.ts +93 -0
- package/dist/loginStatus.d.ts +73 -0
- package/dist/logout.d.ts +44 -0
- package/dist/oidc.d.ts +5 -0
- package/dist/robotClientFallback.d.ts +63 -0
- package/dist/selectTenant.d.ts +8 -0
- package/dist/server.d.ts +8 -0
- package/dist/strategies/auth-strategy.d.ts +3 -0
- package/dist/strategies/browser-strategy.d.ts +4 -0
- package/dist/strategies/node-strategy.d.ts +4 -0
- package/dist/tenantSelection.d.ts +17 -0
- package/dist/tokenExchange.d.ts +13 -0
- package/dist/tokenRefresh.d.ts +27 -0
- package/dist/types.d.ts +5 -0
- package/dist/utils/envFile.d.ts +101 -0
- package/dist/utils/jwt.d.ts +43 -0
- package/dist/utils/platform.d.ts +36 -0
- package/package.json +38 -50
package/dist/index.js
CHANGED
|
@@ -728,6 +728,7 @@ var init_open = __esm(() => {
|
|
|
728
728
|
});
|
|
729
729
|
|
|
730
730
|
// ../filesystem/src/node.ts
|
|
731
|
+
import { randomUUID } from "node:crypto";
|
|
731
732
|
import { existsSync } from "node:fs";
|
|
732
733
|
import * as fs6 from "node:fs/promises";
|
|
733
734
|
import * as os2 from "node:os";
|
|
@@ -809,6 +810,90 @@ class NodeFileSystem {
|
|
|
809
810
|
async mkdir(dirPath) {
|
|
810
811
|
await fs6.mkdir(dirPath, { recursive: true });
|
|
811
812
|
}
|
|
813
|
+
async acquireLock(lockPath) {
|
|
814
|
+
const canonicalPath = await this.canonicalizeLockTarget(lockPath);
|
|
815
|
+
const lockFile = `${canonicalPath}.lock`;
|
|
816
|
+
const ownerId = randomUUID();
|
|
817
|
+
const start = Date.now();
|
|
818
|
+
while (true) {
|
|
819
|
+
try {
|
|
820
|
+
await fs6.writeFile(lockFile, ownerId, { flag: "wx" });
|
|
821
|
+
return this.createLockRelease(lockFile, ownerId);
|
|
822
|
+
} catch (error) {
|
|
823
|
+
if (!this.hasErrnoCode(error, "EEXIST")) {
|
|
824
|
+
throw error;
|
|
825
|
+
}
|
|
826
|
+
const stats = await fs6.stat(lockFile).catch(() => null);
|
|
827
|
+
if (stats && Date.now() - stats.mtimeMs > LOCK_STALE_MS) {
|
|
828
|
+
const reclaimed = await fs6.rm(lockFile, { force: true }).then(() => true).catch(() => false);
|
|
829
|
+
if (reclaimed)
|
|
830
|
+
continue;
|
|
831
|
+
}
|
|
832
|
+
if (Date.now() - start > LOCK_MAX_WAIT_MS) {
|
|
833
|
+
throw new Error(`ELOCKED: timed out waiting for lock on ${canonicalPath}`);
|
|
834
|
+
}
|
|
835
|
+
await new Promise((resolve2) => setTimeout(resolve2, LOCK_RETRY_MIN_MS + Math.random() * LOCK_RETRY_JITTER_MS));
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
async canonicalizeLockTarget(lockPath) {
|
|
840
|
+
const absolute = path2.resolve(lockPath);
|
|
841
|
+
const fullReal = await fs6.realpath(absolute).catch(() => null);
|
|
842
|
+
if (fullReal)
|
|
843
|
+
return fullReal;
|
|
844
|
+
const parent = path2.dirname(absolute);
|
|
845
|
+
const base = path2.basename(absolute);
|
|
846
|
+
const canonicalParent = await fs6.realpath(parent).catch(() => parent);
|
|
847
|
+
return path2.join(canonicalParent, base);
|
|
848
|
+
}
|
|
849
|
+
createLockRelease(lockFile, ownerId) {
|
|
850
|
+
const heartbeatStart = Date.now();
|
|
851
|
+
let heartbeatTimer;
|
|
852
|
+
let stopped = false;
|
|
853
|
+
const stopHeartbeat = () => {
|
|
854
|
+
stopped = true;
|
|
855
|
+
if (heartbeatTimer)
|
|
856
|
+
clearTimeout(heartbeatTimer);
|
|
857
|
+
};
|
|
858
|
+
const scheduleNextHeartbeat = () => {
|
|
859
|
+
if (stopped)
|
|
860
|
+
return;
|
|
861
|
+
if (Date.now() - heartbeatStart >= LOCK_MAX_HOLD_MS) {
|
|
862
|
+
stopped = true;
|
|
863
|
+
return;
|
|
864
|
+
}
|
|
865
|
+
heartbeatTimer = setTimeout(() => {
|
|
866
|
+
runHeartbeat();
|
|
867
|
+
}, LOCK_HEARTBEAT_MS);
|
|
868
|
+
heartbeatTimer.unref?.();
|
|
869
|
+
};
|
|
870
|
+
const runHeartbeat = async () => {
|
|
871
|
+
if (stopped)
|
|
872
|
+
return;
|
|
873
|
+
const current = await fs6.readFile(lockFile, "utf-8").catch(() => null);
|
|
874
|
+
if (stopped)
|
|
875
|
+
return;
|
|
876
|
+
if (current !== ownerId) {
|
|
877
|
+
stopped = true;
|
|
878
|
+
return;
|
|
879
|
+
}
|
|
880
|
+
const now = Date.now() / 1000;
|
|
881
|
+
await fs6.utimes(lockFile, now, now).catch(() => {});
|
|
882
|
+
scheduleNextHeartbeat();
|
|
883
|
+
};
|
|
884
|
+
scheduleNextHeartbeat();
|
|
885
|
+
let released = false;
|
|
886
|
+
return async () => {
|
|
887
|
+
if (released)
|
|
888
|
+
return;
|
|
889
|
+
released = true;
|
|
890
|
+
stopHeartbeat();
|
|
891
|
+
const current = await fs6.readFile(lockFile, "utf-8").catch(() => null);
|
|
892
|
+
if (current === ownerId) {
|
|
893
|
+
await fs6.rm(lockFile, { force: true });
|
|
894
|
+
}
|
|
895
|
+
};
|
|
896
|
+
}
|
|
812
897
|
async rm(filePath) {
|
|
813
898
|
await fs6.rm(filePath, { recursive: true, force: true });
|
|
814
899
|
}
|
|
@@ -854,16 +939,18 @@ class NodeFileSystem {
|
|
|
854
939
|
}
|
|
855
940
|
}
|
|
856
941
|
isEnoent(error) {
|
|
857
|
-
return
|
|
942
|
+
return this.hasErrnoCode(error, "ENOENT");
|
|
943
|
+
}
|
|
944
|
+
hasErrnoCode(error, code) {
|
|
945
|
+
return typeof error === "object" && error !== null && "code" in error && error.code === code;
|
|
858
946
|
}
|
|
859
947
|
}
|
|
948
|
+
var LOCK_HEARTBEAT_MS = 5000, LOCK_STALE_MS = 15000, LOCK_MAX_WAIT_MS = 20000, LOCK_MAX_HOLD_MS = 60000, LOCK_RETRY_MIN_MS = 100, LOCK_RETRY_JITTER_MS = 200;
|
|
860
949
|
var init_node = __esm(() => {
|
|
861
950
|
init_open();
|
|
862
951
|
});
|
|
863
952
|
// ../filesystem/src/index.ts
|
|
864
|
-
var fsInstance, getFileSystem = () =>
|
|
865
|
-
return fsInstance;
|
|
866
|
-
};
|
|
953
|
+
var fsInstance, getFileSystem = () => fsInstance;
|
|
867
954
|
var init_src = __esm(() => {
|
|
868
955
|
init_node();
|
|
869
956
|
init_node();
|
|
@@ -872,7 +959,7 @@ var init_src = __esm(() => {
|
|
|
872
959
|
|
|
873
960
|
// ../../node_modules/@uipath/coreipc/index.js
|
|
874
961
|
var require_coreipc = __commonJS((exports, module) => {
|
|
875
|
-
var __dirname = "/
|
|
962
|
+
var __dirname = "/home/runner/work/cli/cli/node_modules/@uipath/coreipc";
|
|
876
963
|
/*! For license information please see index.js.LICENSE.txt */
|
|
877
964
|
(function(e, t) {
|
|
878
965
|
typeof exports == "object" && typeof module == "object" ? module.exports = t() : typeof define == "function" && define.amd ? define([], t) : typeof exports == "object" ? exports.ipc = t() : e.ipc = t();
|
|
@@ -19065,81 +19152,6 @@ var require_dist = __commonJS((exports) => {
|
|
|
19065
19152
|
__exportStar(require_agent(), exports);
|
|
19066
19153
|
});
|
|
19067
19154
|
|
|
19068
|
-
// src/strategies/browser-strategy.ts
|
|
19069
|
-
var exports_browser_strategy = {};
|
|
19070
|
-
__export(exports_browser_strategy, {
|
|
19071
|
-
BrowserAuthStrategy: () => BrowserAuthStrategy
|
|
19072
|
-
});
|
|
19073
|
-
|
|
19074
|
-
class BrowserAuthStrategy {
|
|
19075
|
-
async execute(url, _redirectUri, expectedState) {
|
|
19076
|
-
const global2 = getGlobalThis();
|
|
19077
|
-
if (!global2?.window) {
|
|
19078
|
-
throw new Error("Browser environment required for authentication");
|
|
19079
|
-
}
|
|
19080
|
-
const screenWidth = global2.window.screen?.width ?? 1024;
|
|
19081
|
-
const screenHeight = global2.window.screen?.height ?? 768;
|
|
19082
|
-
const width = 600;
|
|
19083
|
-
const height = 700;
|
|
19084
|
-
const left = screenWidth / 2 - width / 2;
|
|
19085
|
-
const top = screenHeight / 2 - height / 2;
|
|
19086
|
-
if (!global2.window.open) {
|
|
19087
|
-
throw new Error("window.open is not available");
|
|
19088
|
-
}
|
|
19089
|
-
const popupResult = global2.window.open(url, "uip_auth", `width=${width},height=${height},left=${left},top=${top},resizable=yes,scrollbars=yes,status=yes`);
|
|
19090
|
-
const popup = popupResult;
|
|
19091
|
-
if (!popup) {
|
|
19092
|
-
throw new Error(`Authentication popup was blocked by your browser.
|
|
19093
|
-
|
|
19094
|
-
` + `To continue:
|
|
19095
|
-
` + `1. Look for a popup blocker icon in your address bar
|
|
19096
|
-
` + `2. Allow popups for this site
|
|
19097
|
-
` + `3. Try logging in again
|
|
19098
|
-
|
|
19099
|
-
` + "If using an ad blocker, you may need to temporarily disable it.");
|
|
19100
|
-
}
|
|
19101
|
-
return new Promise((resolve2, reject) => {
|
|
19102
|
-
const messageHandler = (event) => {
|
|
19103
|
-
if (event.data?.type === "UIP_AUTH_CODE" && event.data.code) {
|
|
19104
|
-
if (event.data.state !== expectedState) {
|
|
19105
|
-
cleanup();
|
|
19106
|
-
reject(new Error("OAuth state mismatch — the callback state does not match the expected value. " + "This may indicate a CSRF attack. Please try signing in again."));
|
|
19107
|
-
popup.close();
|
|
19108
|
-
return;
|
|
19109
|
-
}
|
|
19110
|
-
cleanup();
|
|
19111
|
-
resolve2(event.data.code);
|
|
19112
|
-
popup.close();
|
|
19113
|
-
} else if (event.data?.type === "UIP_AUTH_ERROR") {
|
|
19114
|
-
cleanup();
|
|
19115
|
-
const errorMsg = event.data.error || "Authentication failed";
|
|
19116
|
-
reject(new Error(`Authentication failed: ${errorMsg}
|
|
19117
|
-
|
|
19118
|
-
` + "Please check your credentials and try again. " + "If the problem persists, verify your UiPath account is active."));
|
|
19119
|
-
popup.close();
|
|
19120
|
-
}
|
|
19121
|
-
};
|
|
19122
|
-
const cleanup = () => {
|
|
19123
|
-
global2.window?.removeEventListener?.("message", messageHandler);
|
|
19124
|
-
if (timer)
|
|
19125
|
-
clearInterval(timer);
|
|
19126
|
-
};
|
|
19127
|
-
if (global2.window?.addEventListener) {
|
|
19128
|
-
global2.window.addEventListener("message", messageHandler);
|
|
19129
|
-
}
|
|
19130
|
-
const timer = setInterval(() => {
|
|
19131
|
-
if (popup.closed) {
|
|
19132
|
-
cleanup();
|
|
19133
|
-
reject(new Error(`Authentication was cancelled.
|
|
19134
|
-
|
|
19135
|
-
` + "The authentication popup was closed before completing the login process. " + "Please try again and complete the authentication flow."));
|
|
19136
|
-
}
|
|
19137
|
-
}, 1000);
|
|
19138
|
-
});
|
|
19139
|
-
}
|
|
19140
|
-
}
|
|
19141
|
-
var init_browser_strategy = () => {};
|
|
19142
|
-
|
|
19143
19155
|
// src/getBaseHtml.ts
|
|
19144
19156
|
var getBaseHtml = ({ title, message, type }) => {
|
|
19145
19157
|
const icon = type === "success" ? "✓" : "✕";
|
|
@@ -19286,7 +19298,7 @@ var getBaseHtml = ({ title, message, type }) => {
|
|
|
19286
19298
|
};
|
|
19287
19299
|
|
|
19288
19300
|
// src/server.ts
|
|
19289
|
-
var startServer = async ({
|
|
19301
|
+
var AUTH_TIMEOUT_ERROR_CODE = "EAUTHTIMEOUT", startServer = async ({
|
|
19290
19302
|
redirectUri,
|
|
19291
19303
|
timeoutMs = DEFAULT_AUTH_TIMEOUT_MS,
|
|
19292
19304
|
onListening
|
|
@@ -19357,7 +19369,18 @@ var startServer = async ({
|
|
|
19357
19369
|
reject(new Error("No authorization code received"));
|
|
19358
19370
|
return;
|
|
19359
19371
|
});
|
|
19360
|
-
|
|
19372
|
+
const timeoutHandle = setTimeout(() => {
|
|
19373
|
+
server.close();
|
|
19374
|
+
const err = new Error("Authentication timeout");
|
|
19375
|
+
err.code = AUTH_TIMEOUT_ERROR_CODE;
|
|
19376
|
+
reject(err);
|
|
19377
|
+
}, timeoutMs);
|
|
19378
|
+
const bindHost = redirectUri.hostname === "localhost" ? "127.0.0.1" : redirectUri.hostname;
|
|
19379
|
+
server.on("error", (err) => {
|
|
19380
|
+
clearTimeout(timeoutHandle);
|
|
19381
|
+
reject(err);
|
|
19382
|
+
});
|
|
19383
|
+
server.listen(Number(redirectUri.port), bindHost, () => {
|
|
19361
19384
|
if (onListening) {
|
|
19362
19385
|
Promise.resolve(onListening()).catch((err) => {
|
|
19363
19386
|
server.close();
|
|
@@ -19366,10 +19389,6 @@ var startServer = async ({
|
|
|
19366
19389
|
});
|
|
19367
19390
|
}
|
|
19368
19391
|
});
|
|
19369
|
-
const timeoutHandle = setTimeout(() => {
|
|
19370
|
-
server.close();
|
|
19371
|
-
reject(new Error("Authentication timeout"));
|
|
19372
|
-
}, timeoutMs);
|
|
19373
19392
|
server.on("close", () => {
|
|
19374
19393
|
clearTimeout(timeoutHandle);
|
|
19375
19394
|
});
|
|
@@ -19379,6 +19398,81 @@ var init_server = __esm(() => {
|
|
|
19379
19398
|
init_constants();
|
|
19380
19399
|
});
|
|
19381
19400
|
|
|
19401
|
+
// src/strategies/browser-strategy.ts
|
|
19402
|
+
var exports_browser_strategy = {};
|
|
19403
|
+
__export(exports_browser_strategy, {
|
|
19404
|
+
BrowserAuthStrategy: () => BrowserAuthStrategy
|
|
19405
|
+
});
|
|
19406
|
+
|
|
19407
|
+
class BrowserAuthStrategy {
|
|
19408
|
+
async execute(url, _redirectUri, expectedState) {
|
|
19409
|
+
const global2 = getGlobalThis();
|
|
19410
|
+
if (!global2?.window) {
|
|
19411
|
+
throw new Error("Browser environment required for authentication");
|
|
19412
|
+
}
|
|
19413
|
+
const screenWidth = global2.window.screen?.width ?? 1024;
|
|
19414
|
+
const screenHeight = global2.window.screen?.height ?? 768;
|
|
19415
|
+
const width = 600;
|
|
19416
|
+
const height = 700;
|
|
19417
|
+
const left = screenWidth / 2 - width / 2;
|
|
19418
|
+
const top = screenHeight / 2 - height / 2;
|
|
19419
|
+
if (!global2.window.open) {
|
|
19420
|
+
throw new Error("window.open is not available");
|
|
19421
|
+
}
|
|
19422
|
+
const popupResult = global2.window.open(url, "uip_auth", `width=${width},height=${height},left=${left},top=${top},resizable=yes,scrollbars=yes,status=yes`);
|
|
19423
|
+
const popup = popupResult;
|
|
19424
|
+
if (!popup) {
|
|
19425
|
+
throw new Error(`Authentication popup was blocked by your browser.
|
|
19426
|
+
|
|
19427
|
+
` + `To continue:
|
|
19428
|
+
` + `1. Look for a popup blocker icon in your address bar
|
|
19429
|
+
` + `2. Allow popups for this site
|
|
19430
|
+
` + `3. Try logging in again
|
|
19431
|
+
|
|
19432
|
+
` + "If using an ad blocker, you may need to temporarily disable it.");
|
|
19433
|
+
}
|
|
19434
|
+
return new Promise((resolve2, reject) => {
|
|
19435
|
+
const messageHandler = (event) => {
|
|
19436
|
+
if (event.data?.type === "UIP_AUTH_CODE" && event.data.code) {
|
|
19437
|
+
if (event.data.state !== expectedState) {
|
|
19438
|
+
cleanup();
|
|
19439
|
+
reject(new Error("OAuth state mismatch — the callback state does not match the expected value. " + "This may indicate a CSRF attack. Please try signing in again."));
|
|
19440
|
+
popup.close();
|
|
19441
|
+
return;
|
|
19442
|
+
}
|
|
19443
|
+
cleanup();
|
|
19444
|
+
resolve2(event.data.code);
|
|
19445
|
+
popup.close();
|
|
19446
|
+
} else if (event.data?.type === "UIP_AUTH_ERROR") {
|
|
19447
|
+
cleanup();
|
|
19448
|
+
const errorMsg = event.data.error || "Authentication failed";
|
|
19449
|
+
reject(new Error(`Authentication failed: ${errorMsg}
|
|
19450
|
+
|
|
19451
|
+
` + "Please check your credentials and try again. " + "If the problem persists, verify your UiPath account is active."));
|
|
19452
|
+
popup.close();
|
|
19453
|
+
}
|
|
19454
|
+
};
|
|
19455
|
+
const cleanup = () => {
|
|
19456
|
+
global2.window?.removeEventListener?.("message", messageHandler);
|
|
19457
|
+
if (timer)
|
|
19458
|
+
clearInterval(timer);
|
|
19459
|
+
};
|
|
19460
|
+
if (global2.window?.addEventListener) {
|
|
19461
|
+
global2.window.addEventListener("message", messageHandler);
|
|
19462
|
+
}
|
|
19463
|
+
const timer = setInterval(() => {
|
|
19464
|
+
if (popup.closed) {
|
|
19465
|
+
cleanup();
|
|
19466
|
+
reject(new Error(`Authentication was cancelled.
|
|
19467
|
+
|
|
19468
|
+
` + "The authentication popup was closed before completing the login process. " + "Please try again and complete the authentication flow."));
|
|
19469
|
+
}
|
|
19470
|
+
}, 1000);
|
|
19471
|
+
});
|
|
19472
|
+
}
|
|
19473
|
+
}
|
|
19474
|
+
var init_browser_strategy = () => {};
|
|
19475
|
+
|
|
19382
19476
|
// src/strategies/node-strategy.ts
|
|
19383
19477
|
var exports_node_strategy = {};
|
|
19384
19478
|
__export(exports_node_strategy, {
|
|
@@ -19457,30 +19551,7 @@ class InvalidBaseUrlError extends Error {
|
|
|
19457
19551
|
this.name = "InvalidBaseUrlError";
|
|
19458
19552
|
}
|
|
19459
19553
|
}
|
|
19460
|
-
var DEFAULT_SCOPES = [
|
|
19461
|
-
"offline_access",
|
|
19462
|
-
"ProcessMining",
|
|
19463
|
-
"OrchestratorApiUserAccess",
|
|
19464
|
-
"StudioWebBackend",
|
|
19465
|
-
"IdentityServerApi",
|
|
19466
|
-
"ConnectionService",
|
|
19467
|
-
"DataService",
|
|
19468
|
-
"DataServiceApiUserAccess",
|
|
19469
|
-
"DocumentUnderstanding",
|
|
19470
|
-
"EnterpriseContextService",
|
|
19471
|
-
"Directory",
|
|
19472
|
-
"JamJamApi",
|
|
19473
|
-
"LLMGateway",
|
|
19474
|
-
"LLMOps",
|
|
19475
|
-
"OMS",
|
|
19476
|
-
"RCS.FolderAuthorization",
|
|
19477
|
-
"RCS.TagsManagement",
|
|
19478
|
-
"TestmanagerApiUserAccess",
|
|
19479
|
-
"AutomationSolutions",
|
|
19480
|
-
"StudioWebTypeCacheService",
|
|
19481
|
-
"Docs.GPT.Search",
|
|
19482
|
-
"Insights"
|
|
19483
|
-
];
|
|
19554
|
+
var DEFAULT_SCOPES = ["openid", "profile", "offline_access"];
|
|
19484
19555
|
var normalizeAndValidateBaseUrl = (rawUrl) => {
|
|
19485
19556
|
let baseUrl = rawUrl;
|
|
19486
19557
|
if (baseUrl.endsWith("/identity_/")) {
|
|
@@ -19530,7 +19601,8 @@ var resolveConfigAsync = async ({
|
|
|
19530
19601
|
if (!clientSecret && fileAuth.clientSecret) {
|
|
19531
19602
|
clientSecret = fileAuth.clientSecret;
|
|
19532
19603
|
}
|
|
19533
|
-
const
|
|
19604
|
+
const isExternalAppAuth = clientId !== DEFAULT_CLIENT_ID && Boolean(clientSecret);
|
|
19605
|
+
const scopes = customScopes && customScopes.length > 0 ? customScopes : fileAuth.scopes && fileAuth.scopes.length > 0 ? fileAuth.scopes : isExternalAppAuth ? [] : DEFAULT_SCOPES;
|
|
19534
19606
|
return {
|
|
19535
19607
|
clientId,
|
|
19536
19608
|
clientSecret,
|
|
@@ -20250,6 +20322,7 @@ var getTokenExpiration = (accessToken) => {
|
|
|
20250
20322
|
|
|
20251
20323
|
// src/envAuth.ts
|
|
20252
20324
|
var ENV_AUTH_ENABLE_VAR = "UIPATH_CLI_ENABLE_ENV_AUTH";
|
|
20325
|
+
var ENFORCE_ROBOT_AUTH_VAR = "UIPATH_CLI_ENFORCE_ROBOT_AUTH";
|
|
20253
20326
|
var ENV_AUTH_VARS = {
|
|
20254
20327
|
token: "UIPATH_CLI_AUTH_TOKEN",
|
|
20255
20328
|
organizationName: "UIPATH_CLI_ORGANIZATION_NAME",
|
|
@@ -20265,6 +20338,7 @@ class EnvAuthConfigError extends Error {
|
|
|
20265
20338
|
}
|
|
20266
20339
|
}
|
|
20267
20340
|
var isEnvAuthEnabled = () => process.env[ENV_AUTH_ENABLE_VAR] === "true";
|
|
20341
|
+
var isRobotAuthEnforced = () => process.env[ENFORCE_ROBOT_AUTH_VAR] === "true";
|
|
20268
20342
|
var requireEnv = (name) => {
|
|
20269
20343
|
const value = process.env[name];
|
|
20270
20344
|
if (!value) {
|
|
@@ -20306,7 +20380,9 @@ var readAuthFromEnv = () => {
|
|
|
20306
20380
|
expiration
|
|
20307
20381
|
};
|
|
20308
20382
|
};
|
|
20383
|
+
|
|
20309
20384
|
// src/robotClientFallback.ts
|
|
20385
|
+
init_src();
|
|
20310
20386
|
var DEFAULT_TIMEOUT_MS = 1000;
|
|
20311
20387
|
var CLOSE_TIMEOUT_MS = 500;
|
|
20312
20388
|
var NOTICE_SENTINEL = Symbol.for("@uipath/auth/robotFallbackNoticePrinted");
|
|
@@ -20318,6 +20394,35 @@ var printNoticeOnce = () => {
|
|
|
20318
20394
|
catchError(() => process.stderr.write(`Using UiPath Robot credentials. Run 'uip login' for a dedicated session.
|
|
20319
20395
|
`));
|
|
20320
20396
|
};
|
|
20397
|
+
var ROBOT_USER_SERVICES_PIPE = "UiPathUserServices";
|
|
20398
|
+
var ROBOT_USER_SERVICES_ALTERNATE_PIPE = `${ROBOT_USER_SERVICES_PIPE}Alternate`;
|
|
20399
|
+
var PIPE_NAME_MAX_LENGTH = 103;
|
|
20400
|
+
var getRobotIpcPipeNames = async () => {
|
|
20401
|
+
const fs7 = getFileSystem();
|
|
20402
|
+
const username = fs7.env.getenv("USER") ?? fs7.env.getenv("USERNAME");
|
|
20403
|
+
if (!username) {
|
|
20404
|
+
throw new Error("Unable to determine current username");
|
|
20405
|
+
}
|
|
20406
|
+
const tempPath = fs7.env.getenv("TMPDIR") ?? "/tmp/";
|
|
20407
|
+
return [ROBOT_USER_SERVICES_PIPE, ROBOT_USER_SERVICES_ALTERNATE_PIPE].map((baseName) => fs7.path.join(tempPath, `${baseName}_${username}`).substring(0, PIPE_NAME_MAX_LENGTH));
|
|
20408
|
+
};
|
|
20409
|
+
var defaultIsRobotIpcAvailable = async () => {
|
|
20410
|
+
if (process.platform === "win32") {
|
|
20411
|
+
return true;
|
|
20412
|
+
}
|
|
20413
|
+
const [pipeNamesError, pipeNames] = await catchError(getRobotIpcPipeNames());
|
|
20414
|
+
if (pipeNamesError || !pipeNames) {
|
|
20415
|
+
return false;
|
|
20416
|
+
}
|
|
20417
|
+
const fs7 = getFileSystem();
|
|
20418
|
+
for (const pipeName of pipeNames) {
|
|
20419
|
+
const [existsError, exists] = await catchError(fs7.exists(pipeName));
|
|
20420
|
+
if (!existsError && exists === true) {
|
|
20421
|
+
return true;
|
|
20422
|
+
}
|
|
20423
|
+
}
|
|
20424
|
+
return false;
|
|
20425
|
+
};
|
|
20321
20426
|
var withTimeout = (promise, timeoutMs) => new Promise((resolve2, reject) => {
|
|
20322
20427
|
const timer = setTimeout(() => reject(new Error(`Robot IPC call timed out after ${timeoutMs}ms`)), timeoutMs);
|
|
20323
20428
|
promise.then((value) => {
|
|
@@ -20349,14 +20454,20 @@ var defaultLoadModule = async () => {
|
|
|
20349
20454
|
var tryRobotClientFallback = async (options = {}) => {
|
|
20350
20455
|
if (isBrowser())
|
|
20351
20456
|
return;
|
|
20352
|
-
if (
|
|
20353
|
-
|
|
20354
|
-
|
|
20355
|
-
|
|
20356
|
-
|
|
20457
|
+
if (!options.force) {
|
|
20458
|
+
if (process.env.CI || process.env.GITHUB_ACTIONS) {
|
|
20459
|
+
return;
|
|
20460
|
+
}
|
|
20461
|
+
if (process.env.UIPATH_URL) {
|
|
20462
|
+
return;
|
|
20463
|
+
}
|
|
20357
20464
|
}
|
|
20358
20465
|
const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
20466
|
+
const isRobotIpcAvailable = options.isRobotIpcAvailable ?? defaultIsRobotIpcAvailable;
|
|
20359
20467
|
const loadModule = options.loadModule ?? defaultLoadModule;
|
|
20468
|
+
if (!await isRobotIpcAvailable()) {
|
|
20469
|
+
return;
|
|
20470
|
+
}
|
|
20360
20471
|
const mod = await loadModule();
|
|
20361
20472
|
if (!mod)
|
|
20362
20473
|
return;
|
|
@@ -20629,11 +20740,130 @@ function normalizeTokenRefreshFailure() {
|
|
|
20629
20740
|
function normalizeTokenRefreshUnavailableFailure() {
|
|
20630
20741
|
return "token refresh failed before authentication completed";
|
|
20631
20742
|
}
|
|
20632
|
-
|
|
20633
|
-
|
|
20634
|
-
|
|
20743
|
+
function errorMessage(error) {
|
|
20744
|
+
return error instanceof Error ? error.message : String(error);
|
|
20745
|
+
}
|
|
20746
|
+
function computeExpirationThreshold(ensureTokenValidityMinutes) {
|
|
20747
|
+
return new Date(Date.now() + (ensureTokenValidityMinutes ?? 0) * 60 * 1000);
|
|
20748
|
+
}
|
|
20749
|
+
async function runRefreshLocked(inputs) {
|
|
20750
|
+
const {
|
|
20751
|
+
absolutePath,
|
|
20752
|
+
refreshToken: callerRefreshToken,
|
|
20753
|
+
customAuthority,
|
|
20754
|
+
ensureTokenValidityMinutes,
|
|
20755
|
+
loadEnvFile,
|
|
20756
|
+
saveEnvFile,
|
|
20757
|
+
refreshFn,
|
|
20758
|
+
resolveConfig
|
|
20759
|
+
} = inputs;
|
|
20760
|
+
const expirationThreshold = computeExpirationThreshold(ensureTokenValidityMinutes);
|
|
20761
|
+
let fresh;
|
|
20762
|
+
try {
|
|
20763
|
+
fresh = await loadEnvFile({ envPath: absolutePath });
|
|
20764
|
+
} catch (error) {
|
|
20765
|
+
return {
|
|
20766
|
+
kind: "fail",
|
|
20767
|
+
status: {
|
|
20768
|
+
loginStatus: "Refresh Failed",
|
|
20769
|
+
hint: "Could not read the auth file while refreshing. Retry, or run 'uip login' to re-authenticate.",
|
|
20770
|
+
tokenRefresh: {
|
|
20771
|
+
attempted: false,
|
|
20772
|
+
success: false,
|
|
20773
|
+
errorMessage: `auth file read failed: ${errorMessage(error)}`
|
|
20774
|
+
}
|
|
20775
|
+
}
|
|
20776
|
+
};
|
|
20635
20777
|
}
|
|
20636
|
-
const
|
|
20778
|
+
const freshAccess = fresh.UIPATH_ACCESS_TOKEN;
|
|
20779
|
+
const freshExp = freshAccess ? getTokenExpiration(freshAccess) : undefined;
|
|
20780
|
+
if (freshAccess && freshExp && freshExp > expirationThreshold) {
|
|
20781
|
+
return {
|
|
20782
|
+
kind: "ok",
|
|
20783
|
+
accessToken: freshAccess,
|
|
20784
|
+
refreshToken: fresh.UIPATH_REFRESH_TOKEN ?? callerRefreshToken,
|
|
20785
|
+
expiration: freshExp,
|
|
20786
|
+
tokenRefresh: { attempted: false, success: true }
|
|
20787
|
+
};
|
|
20788
|
+
}
|
|
20789
|
+
const tokenForIdP = fresh.UIPATH_REFRESH_TOKEN ?? callerRefreshToken;
|
|
20790
|
+
let refreshedAccess;
|
|
20791
|
+
let refreshedRefresh;
|
|
20792
|
+
try {
|
|
20793
|
+
const config = await resolveConfig({ customAuthority });
|
|
20794
|
+
const refreshed = await refreshFn({
|
|
20795
|
+
refreshToken: tokenForIdP,
|
|
20796
|
+
tokenEndpoint: config.tokenEndpoint,
|
|
20797
|
+
clientId: config.clientId,
|
|
20798
|
+
expectedAuthority: customAuthority
|
|
20799
|
+
});
|
|
20800
|
+
refreshedAccess = refreshed.accessToken;
|
|
20801
|
+
refreshedRefresh = refreshed.refreshToken;
|
|
20802
|
+
} catch (error) {
|
|
20803
|
+
const isOAuthFailure = isTokenRefreshOAuthFailure(error);
|
|
20804
|
+
const hint = isOAuthFailure ? "Run 'uip login' to re-authenticate — the stored refresh token is invalid or expired." : "Token refresh failed. Check your network connection, then retry or run 'uip login' to re-authenticate.";
|
|
20805
|
+
const message = isOAuthFailure ? normalizeTokenRefreshFailure() : normalizeTokenRefreshUnavailableFailure();
|
|
20806
|
+
return {
|
|
20807
|
+
kind: "fail",
|
|
20808
|
+
status: {
|
|
20809
|
+
loginStatus: "Refresh Failed",
|
|
20810
|
+
hint,
|
|
20811
|
+
tokenRefresh: {
|
|
20812
|
+
attempted: true,
|
|
20813
|
+
success: false,
|
|
20814
|
+
errorMessage: message
|
|
20815
|
+
}
|
|
20816
|
+
}
|
|
20817
|
+
};
|
|
20818
|
+
}
|
|
20819
|
+
const refreshedExp = getTokenExpiration(refreshedAccess);
|
|
20820
|
+
if (!refreshedExp || refreshedExp <= new Date) {
|
|
20821
|
+
return {
|
|
20822
|
+
kind: "fail",
|
|
20823
|
+
status: {
|
|
20824
|
+
loginStatus: "Refresh Failed",
|
|
20825
|
+
hint: "The identity server returned an unusable token. Run 'uip login' to re-authenticate.",
|
|
20826
|
+
tokenRefresh: {
|
|
20827
|
+
attempted: true,
|
|
20828
|
+
success: false,
|
|
20829
|
+
errorMessage: "refreshed token has no valid expiration claim"
|
|
20830
|
+
}
|
|
20831
|
+
}
|
|
20832
|
+
};
|
|
20833
|
+
}
|
|
20834
|
+
try {
|
|
20835
|
+
await saveEnvFile({
|
|
20836
|
+
envPath: absolutePath,
|
|
20837
|
+
data: {
|
|
20838
|
+
UIPATH_ACCESS_TOKEN: refreshedAccess,
|
|
20839
|
+
UIPATH_REFRESH_TOKEN: refreshedRefresh
|
|
20840
|
+
},
|
|
20841
|
+
merge: true
|
|
20842
|
+
});
|
|
20843
|
+
return {
|
|
20844
|
+
kind: "ok",
|
|
20845
|
+
accessToken: refreshedAccess,
|
|
20846
|
+
refreshToken: refreshedRefresh,
|
|
20847
|
+
expiration: refreshedExp,
|
|
20848
|
+
tokenRefresh: { attempted: true, success: true }
|
|
20849
|
+
};
|
|
20850
|
+
} catch (error) {
|
|
20851
|
+
const msg = errorMessage(error);
|
|
20852
|
+
return {
|
|
20853
|
+
kind: "ok",
|
|
20854
|
+
accessToken: refreshedAccess,
|
|
20855
|
+
refreshToken: refreshedRefresh,
|
|
20856
|
+
expiration: refreshedExp,
|
|
20857
|
+
persistenceWarning: `Access token refreshed in memory but could not be written to ${absolutePath}: ${msg}. The next CLI invocation will fail until the file can be updated — run 'uip login' to re-authenticate.`,
|
|
20858
|
+
tokenRefresh: {
|
|
20859
|
+
attempted: true,
|
|
20860
|
+
success: true,
|
|
20861
|
+
errorMessage: `persistence failed: ${msg}`
|
|
20862
|
+
}
|
|
20863
|
+
};
|
|
20864
|
+
}
|
|
20865
|
+
}
|
|
20866
|
+
var getLoginStatusWithDeps = async (options = {}, deps = {}) => {
|
|
20637
20867
|
const {
|
|
20638
20868
|
resolveEnvFilePath = resolveEnvFilePathAsync,
|
|
20639
20869
|
loadEnvFile = loadEnvFileAsync,
|
|
@@ -20643,6 +20873,34 @@ var getLoginStatusWithDeps = async (options = {}, deps = {}) => {
|
|
|
20643
20873
|
resolveConfig = resolveConfigAsync,
|
|
20644
20874
|
robotFallback = tryRobotClientFallback
|
|
20645
20875
|
} = deps;
|
|
20876
|
+
if (isRobotAuthEnforced()) {
|
|
20877
|
+
if (isEnvAuthEnabled()) {
|
|
20878
|
+
throw new EnvAuthConfigError(`${ENV_AUTH_ENABLE_VAR}=true and ${ENFORCE_ROBOT_AUTH_VAR}=true ` + `are mutually exclusive. Unset one of them and re-run.`);
|
|
20879
|
+
}
|
|
20880
|
+
const robotCreds = await robotFallback({ force: true });
|
|
20881
|
+
if (!robotCreds) {
|
|
20882
|
+
return {
|
|
20883
|
+
loginStatus: "Not logged in",
|
|
20884
|
+
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.`
|
|
20885
|
+
};
|
|
20886
|
+
}
|
|
20887
|
+
const expiration2 = getTokenExpiration(robotCreds.accessToken);
|
|
20888
|
+
return {
|
|
20889
|
+
loginStatus: "Logged in",
|
|
20890
|
+
accessToken: robotCreds.accessToken,
|
|
20891
|
+
baseUrl: robotCreds.baseUrl,
|
|
20892
|
+
organizationName: robotCreds.organizationName,
|
|
20893
|
+
organizationId: robotCreds.organizationId,
|
|
20894
|
+
tenantName: robotCreds.tenantName,
|
|
20895
|
+
tenantId: robotCreds.tenantId,
|
|
20896
|
+
expiration: expiration2,
|
|
20897
|
+
source: "robot" /* Robot */
|
|
20898
|
+
};
|
|
20899
|
+
}
|
|
20900
|
+
if (isEnvAuthEnabled()) {
|
|
20901
|
+
return readAuthFromEnv();
|
|
20902
|
+
}
|
|
20903
|
+
const { envFilePath = DEFAULT_ENV_FILENAME, ensureTokenValidityMinutes } = options;
|
|
20646
20904
|
const { absolutePath } = await resolveEnvFilePath(envFilePath);
|
|
20647
20905
|
if (absolutePath === undefined) {
|
|
20648
20906
|
const robotCreds = await robotFallback();
|
|
@@ -20679,73 +20937,103 @@ var getLoginStatusWithDeps = async (options = {}, deps = {}) => {
|
|
|
20679
20937
|
let refreshToken = credentials.UIPATH_REFRESH_TOKEN;
|
|
20680
20938
|
let expiration = getTokenExpiration(accessToken);
|
|
20681
20939
|
let persistenceWarning;
|
|
20940
|
+
let lockReleaseFailed = false;
|
|
20682
20941
|
let tokenRefresh;
|
|
20683
|
-
const
|
|
20684
|
-
|
|
20685
|
-
|
|
20686
|
-
|
|
20942
|
+
const outerThreshold = computeExpirationThreshold(ensureTokenValidityMinutes);
|
|
20943
|
+
const tryGlobalCredsHint = async () => {
|
|
20944
|
+
const fs7 = getFs();
|
|
20945
|
+
const globalPath = fs7.path.join(fs7.env.homedir(), envFilePath);
|
|
20946
|
+
if (absolutePath === globalPath)
|
|
20947
|
+
return;
|
|
20948
|
+
if (!await fs7.exists(globalPath))
|
|
20949
|
+
return;
|
|
20687
20950
|
try {
|
|
20688
|
-
const
|
|
20689
|
-
|
|
20690
|
-
|
|
20691
|
-
const
|
|
20692
|
-
|
|
20693
|
-
|
|
20694
|
-
|
|
20695
|
-
|
|
20696
|
-
|
|
20697
|
-
refreshedAccess = refreshed.accessToken;
|
|
20698
|
-
refreshedRefresh = refreshed.refreshToken;
|
|
20699
|
-
} catch (error) {
|
|
20700
|
-
const isOAuthFailure = isTokenRefreshOAuthFailure(error);
|
|
20701
|
-
const hint = isOAuthFailure ? "Run 'uip login' to re-authenticate — the stored refresh token is invalid or expired." : "Token refresh failed. Check your network connection, then retry or run 'uip login' to re-authenticate.";
|
|
20702
|
-
const errorMessage = isOAuthFailure ? normalizeTokenRefreshFailure() : normalizeTokenRefreshUnavailableFailure();
|
|
20703
|
-
return {
|
|
20704
|
-
loginStatus: "Refresh Failed",
|
|
20705
|
-
hint,
|
|
20706
|
-
tokenRefresh: {
|
|
20707
|
-
attempted: true,
|
|
20708
|
-
success: false,
|
|
20709
|
-
errorMessage
|
|
20710
|
-
}
|
|
20711
|
-
};
|
|
20951
|
+
const globalCreds = await loadEnvFile({ envPath: globalPath });
|
|
20952
|
+
if (!globalCreds.UIPATH_ACCESS_TOKEN)
|
|
20953
|
+
return;
|
|
20954
|
+
const globalExp = getTokenExpiration(globalCreds.UIPATH_ACCESS_TOKEN);
|
|
20955
|
+
if (globalExp && globalExp <= new Date)
|
|
20956
|
+
return;
|
|
20957
|
+
return `Local credentials file at ${absolutePath} has expired credentials. Valid credentials exist in ${globalPath}. Remove the local file or run 'uip login' to re-authenticate.`;
|
|
20958
|
+
} catch {
|
|
20959
|
+
return;
|
|
20712
20960
|
}
|
|
20713
|
-
|
|
20714
|
-
|
|
20961
|
+
};
|
|
20962
|
+
if (expiration && expiration <= outerThreshold && refreshToken) {
|
|
20963
|
+
let release;
|
|
20964
|
+
try {
|
|
20965
|
+
release = await getFs().acquireLock(absolutePath);
|
|
20966
|
+
} catch (error) {
|
|
20967
|
+
const msg = errorMessage(error);
|
|
20968
|
+
const globalHint = await tryGlobalCredsHint();
|
|
20969
|
+
if (globalHint) {
|
|
20970
|
+
return {
|
|
20971
|
+
loginStatus: "Expired",
|
|
20972
|
+
accessToken,
|
|
20973
|
+
refreshToken,
|
|
20974
|
+
baseUrl: credentials.UIPATH_URL,
|
|
20975
|
+
organizationName: credentials.UIPATH_ORGANIZATION_NAME,
|
|
20976
|
+
organizationId: credentials.UIPATH_ORGANIZATION_ID,
|
|
20977
|
+
tenantName: credentials.UIPATH_TENANT_NAME,
|
|
20978
|
+
tenantId: credentials.UIPATH_TENANT_ID,
|
|
20979
|
+
expiration,
|
|
20980
|
+
source: "file" /* File */,
|
|
20981
|
+
hint: globalHint,
|
|
20982
|
+
tokenRefresh: {
|
|
20983
|
+
attempted: false,
|
|
20984
|
+
success: false,
|
|
20985
|
+
errorMessage: `lock acquisition failed: ${msg}`
|
|
20986
|
+
}
|
|
20987
|
+
};
|
|
20988
|
+
}
|
|
20715
20989
|
return {
|
|
20716
20990
|
loginStatus: "Refresh Failed",
|
|
20717
|
-
hint: "
|
|
20991
|
+
hint: "Could not acquire the auth-file lock — too many concurrent `uip` processes, or a permission issue on the auth directory. Retry, or run 'uip login' to re-authenticate.",
|
|
20718
20992
|
tokenRefresh: {
|
|
20719
|
-
attempted:
|
|
20993
|
+
attempted: false,
|
|
20720
20994
|
success: false,
|
|
20721
|
-
errorMessage:
|
|
20995
|
+
errorMessage: `lock acquisition failed: ${msg}`
|
|
20722
20996
|
}
|
|
20723
20997
|
};
|
|
20724
20998
|
}
|
|
20725
|
-
|
|
20726
|
-
refreshToken = refreshedRefresh;
|
|
20727
|
-
expiration = refreshedExp;
|
|
20999
|
+
let lockedFailure;
|
|
20728
21000
|
try {
|
|
20729
|
-
await
|
|
20730
|
-
|
|
20731
|
-
|
|
20732
|
-
|
|
20733
|
-
|
|
20734
|
-
|
|
20735
|
-
|
|
21001
|
+
const outcome = await runRefreshLocked({
|
|
21002
|
+
absolutePath,
|
|
21003
|
+
refreshToken,
|
|
21004
|
+
customAuthority: credentials.UIPATH_URL,
|
|
21005
|
+
ensureTokenValidityMinutes,
|
|
21006
|
+
loadEnvFile,
|
|
21007
|
+
saveEnvFile,
|
|
21008
|
+
refreshFn: refreshTokenFn,
|
|
21009
|
+
resolveConfig
|
|
20736
21010
|
});
|
|
20737
|
-
|
|
20738
|
-
|
|
20739
|
-
|
|
20740
|
-
|
|
20741
|
-
|
|
20742
|
-
|
|
20743
|
-
|
|
20744
|
-
|
|
20745
|
-
|
|
20746
|
-
|
|
20747
|
-
|
|
20748
|
-
|
|
21011
|
+
if (outcome.kind === "fail") {
|
|
21012
|
+
lockedFailure = outcome.status;
|
|
21013
|
+
} else {
|
|
21014
|
+
accessToken = outcome.accessToken;
|
|
21015
|
+
refreshToken = outcome.refreshToken;
|
|
21016
|
+
expiration = outcome.expiration;
|
|
21017
|
+
tokenRefresh = outcome.tokenRefresh;
|
|
21018
|
+
if (outcome.persistenceWarning) {
|
|
21019
|
+
persistenceWarning = outcome.persistenceWarning;
|
|
21020
|
+
}
|
|
21021
|
+
}
|
|
21022
|
+
} finally {
|
|
21023
|
+
try {
|
|
21024
|
+
await release();
|
|
21025
|
+
} catch {
|
|
21026
|
+
lockReleaseFailed = true;
|
|
21027
|
+
}
|
|
21028
|
+
}
|
|
21029
|
+
if (lockedFailure) {
|
|
21030
|
+
const globalHint = await tryGlobalCredsHint();
|
|
21031
|
+
const base = globalHint ? {
|
|
21032
|
+
...lockedFailure,
|
|
21033
|
+
loginStatus: "Expired",
|
|
21034
|
+
hint: globalHint
|
|
21035
|
+
} : lockedFailure;
|
|
21036
|
+
return lockReleaseFailed ? { ...base, lockReleaseFailed: true } : base;
|
|
20749
21037
|
}
|
|
20750
21038
|
}
|
|
20751
21039
|
const result = {
|
|
@@ -20760,23 +21048,13 @@ var getLoginStatusWithDeps = async (options = {}, deps = {}) => {
|
|
|
20760
21048
|
expiration,
|
|
20761
21049
|
source: "file" /* File */,
|
|
20762
21050
|
...persistenceWarning ? { hint: persistenceWarning, persistenceFailed: true } : {},
|
|
21051
|
+
...lockReleaseFailed ? { lockReleaseFailed: true } : {},
|
|
20763
21052
|
...tokenRefresh ? { tokenRefresh } : {}
|
|
20764
21053
|
};
|
|
20765
21054
|
if (result.loginStatus === "Expired") {
|
|
20766
|
-
const
|
|
20767
|
-
|
|
20768
|
-
|
|
20769
|
-
try {
|
|
20770
|
-
const globalCreds = await loadEnvFile({
|
|
20771
|
-
envPath: globalPath
|
|
20772
|
-
});
|
|
20773
|
-
if (globalCreds.UIPATH_ACCESS_TOKEN) {
|
|
20774
|
-
const globalExp = getTokenExpiration(globalCreds.UIPATH_ACCESS_TOKEN);
|
|
20775
|
-
if (!globalExp || globalExp > new Date) {
|
|
20776
|
-
result.hint = `Local credentials file at ${absolutePath} has expired credentials. Valid credentials exist in ${globalPath}. Remove the local file or run 'uip login' to re-authenticate.`;
|
|
20777
|
-
}
|
|
20778
|
-
}
|
|
20779
|
-
} catch {}
|
|
21055
|
+
const globalHint = await tryGlobalCredsHint();
|
|
21056
|
+
if (globalHint) {
|
|
21057
|
+
result.hint = globalHint;
|
|
20780
21058
|
}
|
|
20781
21059
|
}
|
|
20782
21060
|
return result;
|
|
@@ -20809,7 +21087,7 @@ var getAuthContext = async (options = {}) => {
|
|
|
20809
21087
|
throw new Error("Tenant ID not available. Ensure UIPATH_TENANT_ID is set.");
|
|
20810
21088
|
}
|
|
20811
21089
|
if (options.requireTenantName && tenantName === undefined) {
|
|
20812
|
-
throw new Error("Tenant not provided and UIPATH_TENANT_NAME not set.
|
|
21090
|
+
throw new Error("Tenant not provided and UIPATH_TENANT_NAME not set. Run 'uip login' to select a tenant, or use 'uip login tenant set <tenant>' to switch tenants.");
|
|
20813
21091
|
}
|
|
20814
21092
|
return {
|
|
20815
21093
|
baseUrl: status.baseUrl,
|
|
@@ -20836,9 +21114,11 @@ var clientCredentialsLogin = async ({
|
|
|
20836
21114
|
const params = {
|
|
20837
21115
|
grant_type: "client_credentials",
|
|
20838
21116
|
client_id: config.clientId,
|
|
20839
|
-
client_secret: config.clientSecret ?? ""
|
|
20840
|
-
scope: config.scopes.join(" ")
|
|
21117
|
+
client_secret: config.clientSecret ?? ""
|
|
20841
21118
|
};
|
|
21119
|
+
if (config.scopes.length > 0) {
|
|
21120
|
+
params.scope = config.scopes.join(" ");
|
|
21121
|
+
}
|
|
20842
21122
|
const tokenResponse = await fetch(config.tokenEndpoint, {
|
|
20843
21123
|
method: "POST",
|
|
20844
21124
|
headers: {
|
|
@@ -21001,29 +21281,24 @@ var interactiveLoginWithDeps = async (options, deps) => {
|
|
|
21001
21281
|
try {
|
|
21002
21282
|
const tokenData = jwtParser(tokens.UIPATH_ACCESS_TOKEN);
|
|
21003
21283
|
const orgId = tokenData.prtId || tokenData.organizationId || tokenData.prt_id;
|
|
21004
|
-
if (typeof orgId
|
|
21005
|
-
|
|
21006
|
-
if (organization) {
|
|
21007
|
-
credentials.UIPATH_ORGANIZATION_NAME = organization;
|
|
21008
|
-
}
|
|
21009
|
-
try {
|
|
21010
|
-
const [tenantName, tenantId, orgName] = await tenantSelector(config.baseUrl, tokens.UIPATH_ACCESS_TOKEN, orgId, tenant, interactive);
|
|
21011
|
-
credentials.UIPATH_ORGANIZATION_NAME = orgName;
|
|
21012
|
-
credentials.UIPATH_TENANT_NAME = tenantName;
|
|
21013
|
-
credentials.UIPATH_TENANT_ID = tenantId;
|
|
21014
|
-
} catch (error) {
|
|
21015
|
-
credentials.UIPATH_TENANT_NAME = undefined;
|
|
21016
|
-
credentials.UIPATH_TENANT_ID = undefined;
|
|
21017
|
-
if (!organization) {
|
|
21018
|
-
credentials.UIPATH_ORGANIZATION_NAME = undefined;
|
|
21019
|
-
}
|
|
21020
|
-
emit({
|
|
21021
|
-
type: "tenant-fetch-failed",
|
|
21022
|
-
message: error instanceof Error ? error.message : String(error)
|
|
21023
|
-
});
|
|
21024
|
-
}
|
|
21284
|
+
if (typeof orgId !== "string" || orgId.length === 0) {
|
|
21285
|
+
throw new Error("Organization ID not available from login token. Cannot establish an active tenant.");
|
|
21025
21286
|
}
|
|
21026
|
-
|
|
21287
|
+
credentials.UIPATH_ORGANIZATION_ID = orgId;
|
|
21288
|
+
if (organization) {
|
|
21289
|
+
credentials.UIPATH_ORGANIZATION_NAME = organization;
|
|
21290
|
+
}
|
|
21291
|
+
const [tenantName, tenantId, orgName] = await tenantSelector(config.baseUrl, tokens.UIPATH_ACCESS_TOKEN, orgId, tenant, interactive);
|
|
21292
|
+
credentials.UIPATH_ORGANIZATION_NAME = orgName;
|
|
21293
|
+
credentials.UIPATH_TENANT_NAME = tenantName;
|
|
21294
|
+
credentials.UIPATH_TENANT_ID = tenantId;
|
|
21295
|
+
} catch (error) {
|
|
21296
|
+
emit({
|
|
21297
|
+
type: "tenant-fetch-failed",
|
|
21298
|
+
message: error instanceof Error ? error.message : String(error)
|
|
21299
|
+
});
|
|
21300
|
+
throw error;
|
|
21301
|
+
}
|
|
21027
21302
|
const fs7 = getFs();
|
|
21028
21303
|
const requestedPath = envFilePath ?? DEFAULT_ENV_FILENAME;
|
|
21029
21304
|
let savePath = requestedPath;
|
|
@@ -21051,11 +21326,25 @@ var interactiveLoginWithDeps = async (options, deps) => {
|
|
|
21051
21326
|
searchDir = parentDir;
|
|
21052
21327
|
}
|
|
21053
21328
|
}
|
|
21054
|
-
|
|
21055
|
-
|
|
21056
|
-
|
|
21057
|
-
|
|
21058
|
-
|
|
21329
|
+
let saveRelease;
|
|
21330
|
+
try {
|
|
21331
|
+
if (typeof fs7.acquireLock === "function") {
|
|
21332
|
+
saveRelease = await fs7.acquireLock(savePath);
|
|
21333
|
+
}
|
|
21334
|
+
} catch {
|
|
21335
|
+
saveRelease = undefined;
|
|
21336
|
+
}
|
|
21337
|
+
try {
|
|
21338
|
+
await saveEnvFile({
|
|
21339
|
+
envPath: savePath,
|
|
21340
|
+
data: credentials,
|
|
21341
|
+
merge: true
|
|
21342
|
+
});
|
|
21343
|
+
} finally {
|
|
21344
|
+
if (saveRelease) {
|
|
21345
|
+
await saveRelease().catch(() => {});
|
|
21346
|
+
}
|
|
21347
|
+
}
|
|
21059
21348
|
const reportedPath = fs7.path.isAbsolute(savePath) ? savePath : fs7.path.join(fs7.env.homedir(), savePath);
|
|
21060
21349
|
emit({
|
|
21061
21350
|
type: "saved",
|
|
@@ -21077,7 +21366,21 @@ async function logoutWithDeps(options, deps = {}) {
|
|
|
21077
21366
|
const fs7 = getFs();
|
|
21078
21367
|
const { absolutePath } = await resolveEnvFilePath(options.file);
|
|
21079
21368
|
if (absolutePath && await fs7.exists(absolutePath)) {
|
|
21080
|
-
|
|
21369
|
+
let release;
|
|
21370
|
+
try {
|
|
21371
|
+
if (typeof fs7.acquireLock === "function") {
|
|
21372
|
+
release = await fs7.acquireLock(absolutePath);
|
|
21373
|
+
}
|
|
21374
|
+
} catch {
|
|
21375
|
+
release = undefined;
|
|
21376
|
+
}
|
|
21377
|
+
try {
|
|
21378
|
+
await fs7.rm(absolutePath);
|
|
21379
|
+
} finally {
|
|
21380
|
+
if (release) {
|
|
21381
|
+
await release().catch(() => {});
|
|
21382
|
+
}
|
|
21383
|
+
}
|
|
21081
21384
|
return {
|
|
21082
21385
|
success: true,
|
|
21083
21386
|
message: `Logged out successfully. Removed ${absolutePath}`,
|
|
@@ -21095,6 +21398,7 @@ async function logout(options) {
|
|
|
21095
21398
|
}
|
|
21096
21399
|
|
|
21097
21400
|
// src/index.ts
|
|
21401
|
+
init_server();
|
|
21098
21402
|
var authenticate = async ({
|
|
21099
21403
|
baseUrl,
|
|
21100
21404
|
clientId,
|
|
@@ -21174,6 +21478,7 @@ export {
|
|
|
21174
21478
|
logout,
|
|
21175
21479
|
loadEnvFileAsync,
|
|
21176
21480
|
isTokenRefreshOAuthFailure,
|
|
21481
|
+
isRobotAuthEnforced,
|
|
21177
21482
|
isNode,
|
|
21178
21483
|
isEnvAuthEnabled,
|
|
21179
21484
|
isBrowser,
|
|
@@ -21191,6 +21496,8 @@ export {
|
|
|
21191
21496
|
EnvAuthConfigError,
|
|
21192
21497
|
ENV_AUTH_VARS,
|
|
21193
21498
|
ENV_AUTH_ENABLE_VAR,
|
|
21499
|
+
ENFORCE_ROBOT_AUTH_VAR,
|
|
21194
21500
|
DEFAULT_ENV_FILENAME,
|
|
21195
|
-
DEFAULT_AUTH_FILENAME
|
|
21501
|
+
DEFAULT_AUTH_FILENAME,
|
|
21502
|
+
AUTH_TIMEOUT_ERROR_CODE
|
|
21196
21503
|
};
|