@uipath/solution-sdk 1.199.0 → 1.201.0-preview.115
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/generated/src/apis/DeploymentsApi.d.ts +13 -1
- package/dist/generated/src/models/DeploymentActivationStatus.d.ts +7 -7
- package/dist/generated/src/models/DeploymentOperation.d.ts +6 -6
- package/dist/generated/src/models/DeploymentOperationStatus.d.ts +5 -5
- package/dist/generated/src/models/DeploymentStatus.d.ts +10 -10
- package/dist/generated/src/models/DeploymentType.d.ts +2 -2
- package/dist/generated/src/models/DeploymentUpgradeRequest.d.ts +38 -0
- package/dist/generated/src/models/DeploymentUpgradeType.d.ts +4 -4
- package/dist/generated/src/models/ExtendedPackageVersionState.d.ts +4 -4
- package/dist/generated/src/models/OrderByDirection.d.ts +2 -2
- package/dist/generated/src/models/OverwriteType.d.ts +2 -2
- package/dist/generated/src/models/PackageVersionOrigin.d.ts +4 -4
- package/dist/generated/src/models/ProjectImportStatus.d.ts +4 -4
- package/dist/generated/src/models/WorkflowAction.d.ts +6 -6
- package/dist/generated/src/models/index.d.ts +1 -0
- package/dist/index.js +14431 -13727
- package/dist/resources/index.js +32323 -0
- package/dist/scripts/generate-sdk.js +2 -1
- package/dist/solution-auth.js +2292 -0
- package/dist/src/deployments-auto-install.d.ts +55 -0
- package/dist/src/index.d.ts +4 -1
- package/dist/src/resources/commands/project-utils.d.ts +64 -0
- package/dist/src/resources/index.d.ts +22 -0
- package/dist/src/resources/providers/file-storage-provider.d.ts +11 -0
- package/dist/src/resources/providers/resource-builder-init.d.ts +12 -0
- package/dist/src/resources/providers/solution-access-provider.d.ts +18 -0
- package/dist/src/resources/services/entry-point-spec-enhancer.d.ts +31 -0
- package/dist/src/resources/services/local-resource-matcher.d.ts +27 -0
- package/dist/src/resources/services/project-artifacts-service.d.ts +44 -0
- package/dist/src/resources/services/resource-refresh-service.d.ts +34 -0
- package/dist/src/resources/services/solution-manifest.d.ts +9 -0
- package/dist/src/resources/services/sync-resources-from-bindings.d.ts +133 -0
- package/dist/src/search-package-versions.d.ts +46 -0
- package/dist/src/solution-auth.d.ts +13 -0
- package/dist/src/solution-file.d.ts +13 -1
- package/package.json +10 -2
|
@@ -0,0 +1,2292 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
function __accessProp(key) {
|
|
8
|
+
return this[key];
|
|
9
|
+
}
|
|
10
|
+
var __toESMCache_node;
|
|
11
|
+
var __toESMCache_esm;
|
|
12
|
+
var __toESM = (mod, isNodeMode, target) => {
|
|
13
|
+
var canCache = mod != null && typeof mod === "object";
|
|
14
|
+
if (canCache) {
|
|
15
|
+
var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
|
|
16
|
+
var cached = cache.get(mod);
|
|
17
|
+
if (cached)
|
|
18
|
+
return cached;
|
|
19
|
+
}
|
|
20
|
+
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
21
|
+
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
22
|
+
for (let key of __getOwnPropNames(mod))
|
|
23
|
+
if (!__hasOwnProp.call(to, key))
|
|
24
|
+
__defProp(to, key, {
|
|
25
|
+
get: __accessProp.bind(mod, key),
|
|
26
|
+
enumerable: true
|
|
27
|
+
});
|
|
28
|
+
if (canCache)
|
|
29
|
+
cache.set(mod, to);
|
|
30
|
+
return to;
|
|
31
|
+
};
|
|
32
|
+
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
33
|
+
var __returnValue = (v) => v;
|
|
34
|
+
function __exportSetter(name, newValue) {
|
|
35
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
36
|
+
}
|
|
37
|
+
var __export = (target, all) => {
|
|
38
|
+
for (var name in all)
|
|
39
|
+
__defProp(target, name, {
|
|
40
|
+
get: all[name],
|
|
41
|
+
enumerable: true,
|
|
42
|
+
configurable: true,
|
|
43
|
+
set: __exportSetter.bind(all, name)
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
47
|
+
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
48
|
+
|
|
49
|
+
// ../auth/src/catch-error.ts
|
|
50
|
+
function isPromiseLike(value) {
|
|
51
|
+
return value !== null && typeof value === "object" && typeof value.then === "function";
|
|
52
|
+
}
|
|
53
|
+
function catchError(fnOrPromise) {
|
|
54
|
+
if (isPromiseLike(fnOrPromise)) {
|
|
55
|
+
return settlePromiseLike(fnOrPromise);
|
|
56
|
+
}
|
|
57
|
+
try {
|
|
58
|
+
const result = fnOrPromise();
|
|
59
|
+
if (isPromiseLike(result)) {
|
|
60
|
+
return settlePromiseLike(result);
|
|
61
|
+
}
|
|
62
|
+
return [undefined, result];
|
|
63
|
+
} catch (error) {
|
|
64
|
+
return [
|
|
65
|
+
error instanceof Error ? error : new Error(String(error)),
|
|
66
|
+
undefined
|
|
67
|
+
];
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function settlePromiseLike(thenable) {
|
|
71
|
+
return Promise.resolve(thenable).then((data) => [undefined, data]).catch((error) => [
|
|
72
|
+
error instanceof Error ? error : new Error(String(error)),
|
|
73
|
+
undefined
|
|
74
|
+
]);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// ../auth/src/constants.ts
|
|
78
|
+
var UIPATH_HOME_DIR = ".uipath", AUTH_FILENAME = ".auth", DEFAULT_BASE_URL = "https://cloud.uipath.com", DEFAULT_AUTH_TIMEOUT_MS;
|
|
79
|
+
var init_constants = __esm(() => {
|
|
80
|
+
DEFAULT_AUTH_TIMEOUT_MS = 5 * 60 * 1000;
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
// ../auth/src/utils/platform.ts
|
|
84
|
+
function isBrowser() {
|
|
85
|
+
return typeof globalThis !== "undefined" && "window" in globalThis && "document" in globalThis;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// ../../node_modules/is-inside-container/node_modules/is-docker/index.js
|
|
89
|
+
import fs from "node:fs";
|
|
90
|
+
function hasDockerEnv() {
|
|
91
|
+
try {
|
|
92
|
+
fs.statSync("/.dockerenv");
|
|
93
|
+
return true;
|
|
94
|
+
} catch {
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
function hasDockerCGroup() {
|
|
99
|
+
try {
|
|
100
|
+
return fs.readFileSync("/proc/self/cgroup", "utf8").includes("docker");
|
|
101
|
+
} catch {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
function isDocker() {
|
|
106
|
+
if (isDockerCached === undefined) {
|
|
107
|
+
isDockerCached = hasDockerEnv() || hasDockerCGroup();
|
|
108
|
+
}
|
|
109
|
+
return isDockerCached;
|
|
110
|
+
}
|
|
111
|
+
var isDockerCached;
|
|
112
|
+
var init_is_docker = () => {};
|
|
113
|
+
|
|
114
|
+
// ../../node_modules/is-inside-container/index.js
|
|
115
|
+
import fs2 from "node:fs";
|
|
116
|
+
function isInsideContainer() {
|
|
117
|
+
if (cachedResult === undefined) {
|
|
118
|
+
cachedResult = hasContainerEnv() || isDocker();
|
|
119
|
+
}
|
|
120
|
+
return cachedResult;
|
|
121
|
+
}
|
|
122
|
+
var cachedResult, hasContainerEnv = () => {
|
|
123
|
+
try {
|
|
124
|
+
fs2.statSync("/run/.containerenv");
|
|
125
|
+
return true;
|
|
126
|
+
} catch {
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
var init_is_inside_container = __esm(() => {
|
|
131
|
+
init_is_docker();
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
// ../../node_modules/wsl-utils/node_modules/is-wsl/index.js
|
|
135
|
+
import process2 from "node:process";
|
|
136
|
+
import os from "node:os";
|
|
137
|
+
import fs3 from "node:fs";
|
|
138
|
+
var isWsl = () => {
|
|
139
|
+
if (process2.platform !== "linux") {
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
if (os.release().toLowerCase().includes("microsoft")) {
|
|
143
|
+
if (isInsideContainer()) {
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
return true;
|
|
147
|
+
}
|
|
148
|
+
try {
|
|
149
|
+
if (fs3.readFileSync("/proc/version", "utf8").toLowerCase().includes("microsoft")) {
|
|
150
|
+
return !isInsideContainer();
|
|
151
|
+
}
|
|
152
|
+
} catch {}
|
|
153
|
+
if (fs3.existsSync("/proc/sys/fs/binfmt_misc/WSLInterop") || fs3.existsSync("/run/WSL")) {
|
|
154
|
+
return !isInsideContainer();
|
|
155
|
+
}
|
|
156
|
+
return false;
|
|
157
|
+
}, is_wsl_default;
|
|
158
|
+
var init_is_wsl = __esm(() => {
|
|
159
|
+
init_is_inside_container();
|
|
160
|
+
is_wsl_default = process2.env.__IS_WSL_TEST__ ? isWsl : isWsl();
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
// ../../node_modules/powershell-utils/index.js
|
|
164
|
+
import process3 from "node:process";
|
|
165
|
+
import { Buffer as Buffer2 } from "node:buffer";
|
|
166
|
+
import { promisify } from "node:util";
|
|
167
|
+
import childProcess from "node:child_process";
|
|
168
|
+
var execFile, powerShellPath = () => `${process3.env.SYSTEMROOT || process3.env.windir || String.raw`C:\Windows`}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe`, executePowerShell = async (command, options = {}) => {
|
|
169
|
+
const {
|
|
170
|
+
powerShellPath: psPath,
|
|
171
|
+
...execFileOptions
|
|
172
|
+
} = options;
|
|
173
|
+
const encodedCommand = executePowerShell.encodeCommand(command);
|
|
174
|
+
return execFile(psPath ?? powerShellPath(), [
|
|
175
|
+
...executePowerShell.argumentsPrefix,
|
|
176
|
+
encodedCommand
|
|
177
|
+
], {
|
|
178
|
+
encoding: "utf8",
|
|
179
|
+
...execFileOptions
|
|
180
|
+
});
|
|
181
|
+
};
|
|
182
|
+
var init_powershell_utils = __esm(() => {
|
|
183
|
+
execFile = promisify(childProcess.execFile);
|
|
184
|
+
executePowerShell.argumentsPrefix = [
|
|
185
|
+
"-NoProfile",
|
|
186
|
+
"-NonInteractive",
|
|
187
|
+
"-ExecutionPolicy",
|
|
188
|
+
"Bypass",
|
|
189
|
+
"-EncodedCommand"
|
|
190
|
+
];
|
|
191
|
+
executePowerShell.encodeCommand = (command) => Buffer2.from(command, "utf16le").toString("base64");
|
|
192
|
+
executePowerShell.escapeArgument = (value) => `'${String(value).replaceAll("'", "''")}'`;
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
// ../../node_modules/wsl-utils/utilities.js
|
|
196
|
+
function parseMountPointFromConfig(content) {
|
|
197
|
+
for (const line of content.split(`
|
|
198
|
+
`)) {
|
|
199
|
+
if (/^\s*#/.test(line)) {
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
const match = /^\s*root\s*=\s*(?<mountPoint>"[^"]*"|'[^']*'|[^#]*)/.exec(line);
|
|
203
|
+
if (!match) {
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
return match.groups.mountPoint.trim().replaceAll(/^["']|["']$/g, "");
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// ../../node_modules/wsl-utils/index.js
|
|
211
|
+
import { promisify as promisify2 } from "node:util";
|
|
212
|
+
import childProcess2 from "node:child_process";
|
|
213
|
+
import fs4, { constants as fsConstants } from "node:fs/promises";
|
|
214
|
+
var execFile2, wslDrivesMountPoint, powerShellPathFromWsl = async () => {
|
|
215
|
+
const mountPoint = await wslDrivesMountPoint();
|
|
216
|
+
return `${mountPoint}c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe`;
|
|
217
|
+
}, powerShellPath2, canAccessPowerShellPromise, canAccessPowerShell = async () => {
|
|
218
|
+
canAccessPowerShellPromise ??= (async () => {
|
|
219
|
+
try {
|
|
220
|
+
const psPath = await powerShellPath2();
|
|
221
|
+
await fs4.access(psPath, fsConstants.X_OK);
|
|
222
|
+
return true;
|
|
223
|
+
} catch {
|
|
224
|
+
return false;
|
|
225
|
+
}
|
|
226
|
+
})();
|
|
227
|
+
return canAccessPowerShellPromise;
|
|
228
|
+
}, wslDefaultBrowser = async () => {
|
|
229
|
+
const psPath = await powerShellPath2();
|
|
230
|
+
const command = String.raw`(Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice").ProgId`;
|
|
231
|
+
const { stdout } = await executePowerShell(command, { powerShellPath: psPath });
|
|
232
|
+
return stdout.trim();
|
|
233
|
+
}, convertWslPathToWindows = async (path) => {
|
|
234
|
+
if (/^[a-z]+:\/\//i.test(path)) {
|
|
235
|
+
return path;
|
|
236
|
+
}
|
|
237
|
+
try {
|
|
238
|
+
const { stdout } = await execFile2("wslpath", ["-aw", path], { encoding: "utf8" });
|
|
239
|
+
return stdout.trim();
|
|
240
|
+
} catch {
|
|
241
|
+
return path;
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
var init_wsl_utils = __esm(() => {
|
|
245
|
+
init_is_wsl();
|
|
246
|
+
init_powershell_utils();
|
|
247
|
+
init_is_wsl();
|
|
248
|
+
execFile2 = promisify2(childProcess2.execFile);
|
|
249
|
+
wslDrivesMountPoint = (() => {
|
|
250
|
+
const defaultMountPoint = "/mnt/";
|
|
251
|
+
let mountPoint;
|
|
252
|
+
return async function() {
|
|
253
|
+
if (mountPoint) {
|
|
254
|
+
return mountPoint;
|
|
255
|
+
}
|
|
256
|
+
const configFilePath = "/etc/wsl.conf";
|
|
257
|
+
let isConfigFileExists = false;
|
|
258
|
+
try {
|
|
259
|
+
await fs4.access(configFilePath, fsConstants.F_OK);
|
|
260
|
+
isConfigFileExists = true;
|
|
261
|
+
} catch {}
|
|
262
|
+
if (!isConfigFileExists) {
|
|
263
|
+
return defaultMountPoint;
|
|
264
|
+
}
|
|
265
|
+
const configContent = await fs4.readFile(configFilePath, { encoding: "utf8" });
|
|
266
|
+
const parsedMountPoint = parseMountPointFromConfig(configContent);
|
|
267
|
+
if (parsedMountPoint === undefined) {
|
|
268
|
+
return defaultMountPoint;
|
|
269
|
+
}
|
|
270
|
+
mountPoint = parsedMountPoint;
|
|
271
|
+
mountPoint = mountPoint.endsWith("/") ? mountPoint : `${mountPoint}/`;
|
|
272
|
+
return mountPoint;
|
|
273
|
+
};
|
|
274
|
+
})();
|
|
275
|
+
powerShellPath2 = is_wsl_default ? powerShellPathFromWsl : powerShellPath;
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
// ../../node_modules/open/node_modules/define-lazy-prop/index.js
|
|
279
|
+
function defineLazyProperty(object, propertyName, valueGetter) {
|
|
280
|
+
const define = (value) => Object.defineProperty(object, propertyName, { value, enumerable: true, writable: true });
|
|
281
|
+
Object.defineProperty(object, propertyName, {
|
|
282
|
+
configurable: true,
|
|
283
|
+
enumerable: true,
|
|
284
|
+
get() {
|
|
285
|
+
const result = valueGetter();
|
|
286
|
+
define(result);
|
|
287
|
+
return result;
|
|
288
|
+
},
|
|
289
|
+
set(value) {
|
|
290
|
+
define(value);
|
|
291
|
+
}
|
|
292
|
+
});
|
|
293
|
+
return object;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// ../../node_modules/default-browser-id/index.js
|
|
297
|
+
import { promisify as promisify3 } from "node:util";
|
|
298
|
+
import process4 from "node:process";
|
|
299
|
+
import { execFile as execFile3 } from "node:child_process";
|
|
300
|
+
async function defaultBrowserId() {
|
|
301
|
+
if (process4.platform !== "darwin") {
|
|
302
|
+
throw new Error("macOS only");
|
|
303
|
+
}
|
|
304
|
+
const { stdout } = await execFileAsync("defaults", ["read", "com.apple.LaunchServices/com.apple.launchservices.secure", "LSHandlers"]);
|
|
305
|
+
const match = /LSHandlerRoleAll = "(?!-)(?<id>[^"]+?)";\s+?LSHandlerURLScheme = (?:http|https);/.exec(stdout);
|
|
306
|
+
const browserId = match?.groups.id ?? "com.apple.Safari";
|
|
307
|
+
if (browserId === "com.apple.safari") {
|
|
308
|
+
return "com.apple.Safari";
|
|
309
|
+
}
|
|
310
|
+
return browserId;
|
|
311
|
+
}
|
|
312
|
+
var execFileAsync;
|
|
313
|
+
var init_default_browser_id = __esm(() => {
|
|
314
|
+
execFileAsync = promisify3(execFile3);
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
// ../../node_modules/run-applescript/index.js
|
|
318
|
+
import process5 from "node:process";
|
|
319
|
+
import { promisify as promisify4 } from "node:util";
|
|
320
|
+
import { execFile as execFile4, execFileSync } from "node:child_process";
|
|
321
|
+
async function runAppleScript(script, { humanReadableOutput = true, signal } = {}) {
|
|
322
|
+
if (process5.platform !== "darwin") {
|
|
323
|
+
throw new Error("macOS only");
|
|
324
|
+
}
|
|
325
|
+
const outputArguments = humanReadableOutput ? [] : ["-ss"];
|
|
326
|
+
const execOptions = {};
|
|
327
|
+
if (signal) {
|
|
328
|
+
execOptions.signal = signal;
|
|
329
|
+
}
|
|
330
|
+
const { stdout } = await execFileAsync2("osascript", ["-e", script, outputArguments], execOptions);
|
|
331
|
+
return stdout.trim();
|
|
332
|
+
}
|
|
333
|
+
var execFileAsync2;
|
|
334
|
+
var init_run_applescript = __esm(() => {
|
|
335
|
+
execFileAsync2 = promisify4(execFile4);
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
// ../../node_modules/bundle-name/index.js
|
|
339
|
+
async function bundleName(bundleId) {
|
|
340
|
+
return runAppleScript(`tell application "Finder" to set app_path to application file id "${bundleId}" as string
|
|
341
|
+
tell application "System Events" to get value of property list item "CFBundleName" of property list file (app_path & ":Contents:Info.plist")`);
|
|
342
|
+
}
|
|
343
|
+
var init_bundle_name = __esm(() => {
|
|
344
|
+
init_run_applescript();
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
// ../../node_modules/default-browser/windows.js
|
|
348
|
+
import { promisify as promisify5 } from "node:util";
|
|
349
|
+
import { execFile as execFile5 } from "node:child_process";
|
|
350
|
+
async function defaultBrowser(_execFileAsync = execFileAsync3) {
|
|
351
|
+
const { stdout } = await _execFileAsync("reg", [
|
|
352
|
+
"QUERY",
|
|
353
|
+
" HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\http\\UserChoice",
|
|
354
|
+
"/v",
|
|
355
|
+
"ProgId"
|
|
356
|
+
]);
|
|
357
|
+
const match = /ProgId\s*REG_SZ\s*(?<id>\S+)/.exec(stdout);
|
|
358
|
+
if (!match) {
|
|
359
|
+
throw new UnknownBrowserError(`Cannot find Windows browser in stdout: ${JSON.stringify(stdout)}`);
|
|
360
|
+
}
|
|
361
|
+
const { id } = match.groups;
|
|
362
|
+
const dotIndex = id.lastIndexOf(".");
|
|
363
|
+
const hyphenIndex = id.lastIndexOf("-");
|
|
364
|
+
const baseIdByDot = dotIndex === -1 ? undefined : id.slice(0, dotIndex);
|
|
365
|
+
const baseIdByHyphen = hyphenIndex === -1 ? undefined : id.slice(0, hyphenIndex);
|
|
366
|
+
return windowsBrowserProgIds[id] ?? windowsBrowserProgIds[baseIdByDot] ?? windowsBrowserProgIds[baseIdByHyphen] ?? { name: id, id };
|
|
367
|
+
}
|
|
368
|
+
var execFileAsync3, windowsBrowserProgIds, _windowsBrowserProgIdMap, UnknownBrowserError;
|
|
369
|
+
var init_windows = __esm(() => {
|
|
370
|
+
execFileAsync3 = promisify5(execFile5);
|
|
371
|
+
windowsBrowserProgIds = {
|
|
372
|
+
MSEdgeHTM: { name: "Edge", id: "com.microsoft.edge" },
|
|
373
|
+
MSEdgeBHTML: { name: "Edge Beta", id: "com.microsoft.edge.beta" },
|
|
374
|
+
MSEdgeDHTML: { name: "Edge Dev", id: "com.microsoft.edge.dev" },
|
|
375
|
+
AppXq0fevzme2pys62n3e0fbqa7peapykr8v: { name: "Edge", id: "com.microsoft.edge.old" },
|
|
376
|
+
ChromeHTML: { name: "Chrome", id: "com.google.chrome" },
|
|
377
|
+
ChromeBHTML: { name: "Chrome Beta", id: "com.google.chrome.beta" },
|
|
378
|
+
ChromeDHTML: { name: "Chrome Dev", id: "com.google.chrome.dev" },
|
|
379
|
+
ChromiumHTM: { name: "Chromium", id: "org.chromium.Chromium" },
|
|
380
|
+
BraveHTML: { name: "Brave", id: "com.brave.Browser" },
|
|
381
|
+
BraveBHTML: { name: "Brave Beta", id: "com.brave.Browser.beta" },
|
|
382
|
+
BraveDHTML: { name: "Brave Dev", id: "com.brave.Browser.dev" },
|
|
383
|
+
BraveSSHTM: { name: "Brave Nightly", id: "com.brave.Browser.nightly" },
|
|
384
|
+
FirefoxURL: { name: "Firefox", id: "org.mozilla.firefox" },
|
|
385
|
+
OperaStable: { name: "Opera", id: "com.operasoftware.Opera" },
|
|
386
|
+
VivaldiHTM: { name: "Vivaldi", id: "com.vivaldi.Vivaldi" },
|
|
387
|
+
"IE.HTTP": { name: "Internet Explorer", id: "com.microsoft.ie" }
|
|
388
|
+
};
|
|
389
|
+
_windowsBrowserProgIdMap = new Map(Object.entries(windowsBrowserProgIds));
|
|
390
|
+
UnknownBrowserError = class UnknownBrowserError extends Error {
|
|
391
|
+
};
|
|
392
|
+
});
|
|
393
|
+
|
|
394
|
+
// ../../node_modules/default-browser/index.js
|
|
395
|
+
import { promisify as promisify6 } from "node:util";
|
|
396
|
+
import process6 from "node:process";
|
|
397
|
+
import { execFile as execFile6 } from "node:child_process";
|
|
398
|
+
async function defaultBrowser2() {
|
|
399
|
+
if (process6.platform === "darwin") {
|
|
400
|
+
const id = await defaultBrowserId();
|
|
401
|
+
const name = await bundleName(id);
|
|
402
|
+
return { name, id };
|
|
403
|
+
}
|
|
404
|
+
if (process6.platform === "linux") {
|
|
405
|
+
const { stdout } = await execFileAsync4("xdg-mime", ["query", "default", "x-scheme-handler/http"]);
|
|
406
|
+
const id = stdout.trim();
|
|
407
|
+
const name = titleize(id.replace(/.desktop$/, "").replace("-", " "));
|
|
408
|
+
return { name, id };
|
|
409
|
+
}
|
|
410
|
+
if (process6.platform === "win32") {
|
|
411
|
+
return defaultBrowser();
|
|
412
|
+
}
|
|
413
|
+
throw new Error("Only macOS, Linux, and Windows are supported");
|
|
414
|
+
}
|
|
415
|
+
var execFileAsync4, titleize = (string) => string.toLowerCase().replaceAll(/(?:^|\s|-)\S/g, (x) => x.toUpperCase());
|
|
416
|
+
var init_default_browser = __esm(() => {
|
|
417
|
+
init_default_browser_id();
|
|
418
|
+
init_bundle_name();
|
|
419
|
+
init_windows();
|
|
420
|
+
init_windows();
|
|
421
|
+
execFileAsync4 = promisify6(execFile6);
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
// ../../node_modules/is-in-ssh/index.js
|
|
425
|
+
import process7 from "node:process";
|
|
426
|
+
var isInSsh, is_in_ssh_default;
|
|
427
|
+
var init_is_in_ssh = __esm(() => {
|
|
428
|
+
isInSsh = Boolean(process7.env.SSH_CONNECTION || process7.env.SSH_CLIENT || process7.env.SSH_TTY);
|
|
429
|
+
is_in_ssh_default = isInSsh;
|
|
430
|
+
});
|
|
431
|
+
|
|
432
|
+
// ../../node_modules/open/index.js
|
|
433
|
+
var exports_open = {};
|
|
434
|
+
__export(exports_open, {
|
|
435
|
+
openApp: () => openApp,
|
|
436
|
+
default: () => open_default,
|
|
437
|
+
apps: () => apps
|
|
438
|
+
});
|
|
439
|
+
import process8 from "node:process";
|
|
440
|
+
import path from "node:path";
|
|
441
|
+
import { fileURLToPath } from "node:url";
|
|
442
|
+
import childProcess3 from "node:child_process";
|
|
443
|
+
import fs5, { constants as fsConstants2 } from "node:fs/promises";
|
|
444
|
+
function detectArchBinary(binary) {
|
|
445
|
+
if (typeof binary === "string" || Array.isArray(binary)) {
|
|
446
|
+
return binary;
|
|
447
|
+
}
|
|
448
|
+
const { [arch]: archBinary } = binary;
|
|
449
|
+
if (!archBinary) {
|
|
450
|
+
throw new Error(`${arch} is not supported`);
|
|
451
|
+
}
|
|
452
|
+
return archBinary;
|
|
453
|
+
}
|
|
454
|
+
function detectPlatformBinary({ [platform]: platformBinary }, { wsl } = {}) {
|
|
455
|
+
if (wsl && is_wsl_default) {
|
|
456
|
+
return detectArchBinary(wsl);
|
|
457
|
+
}
|
|
458
|
+
if (!platformBinary) {
|
|
459
|
+
throw new Error(`${platform} is not supported`);
|
|
460
|
+
}
|
|
461
|
+
return detectArchBinary(platformBinary);
|
|
462
|
+
}
|
|
463
|
+
var fallbackAttemptSymbol, __dirname2, localXdgOpenPath, platform, arch, tryEachApp = async (apps, opener) => {
|
|
464
|
+
if (apps.length === 0) {
|
|
465
|
+
return;
|
|
466
|
+
}
|
|
467
|
+
const errors = [];
|
|
468
|
+
for (const app of apps) {
|
|
469
|
+
try {
|
|
470
|
+
return await opener(app);
|
|
471
|
+
} catch (error) {
|
|
472
|
+
errors.push(error);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
throw new AggregateError(errors, "Failed to open in all supported apps");
|
|
476
|
+
}, baseOpen = async (options) => {
|
|
477
|
+
options = {
|
|
478
|
+
wait: false,
|
|
479
|
+
background: false,
|
|
480
|
+
newInstance: false,
|
|
481
|
+
allowNonzeroExitCode: false,
|
|
482
|
+
...options
|
|
483
|
+
};
|
|
484
|
+
const isFallbackAttempt = options[fallbackAttemptSymbol] === true;
|
|
485
|
+
delete options[fallbackAttemptSymbol];
|
|
486
|
+
if (Array.isArray(options.app)) {
|
|
487
|
+
return tryEachApp(options.app, (singleApp) => baseOpen({
|
|
488
|
+
...options,
|
|
489
|
+
app: singleApp,
|
|
490
|
+
[fallbackAttemptSymbol]: true
|
|
491
|
+
}));
|
|
492
|
+
}
|
|
493
|
+
let { name: app, arguments: appArguments = [] } = options.app ?? {};
|
|
494
|
+
appArguments = [...appArguments];
|
|
495
|
+
if (Array.isArray(app)) {
|
|
496
|
+
return tryEachApp(app, (appName) => baseOpen({
|
|
497
|
+
...options,
|
|
498
|
+
app: {
|
|
499
|
+
name: appName,
|
|
500
|
+
arguments: appArguments
|
|
501
|
+
},
|
|
502
|
+
[fallbackAttemptSymbol]: true
|
|
503
|
+
}));
|
|
504
|
+
}
|
|
505
|
+
if (app === "browser" || app === "browserPrivate") {
|
|
506
|
+
const ids = {
|
|
507
|
+
"com.google.chrome": "chrome",
|
|
508
|
+
"google-chrome.desktop": "chrome",
|
|
509
|
+
"com.brave.browser": "brave",
|
|
510
|
+
"org.mozilla.firefox": "firefox",
|
|
511
|
+
"firefox.desktop": "firefox",
|
|
512
|
+
"com.microsoft.msedge": "edge",
|
|
513
|
+
"com.microsoft.edge": "edge",
|
|
514
|
+
"com.microsoft.edgemac": "edge",
|
|
515
|
+
"microsoft-edge.desktop": "edge",
|
|
516
|
+
"com.apple.safari": "safari"
|
|
517
|
+
};
|
|
518
|
+
const flags = {
|
|
519
|
+
chrome: "--incognito",
|
|
520
|
+
brave: "--incognito",
|
|
521
|
+
firefox: "--private-window",
|
|
522
|
+
edge: "--inPrivate"
|
|
523
|
+
};
|
|
524
|
+
let browser;
|
|
525
|
+
if (is_wsl_default) {
|
|
526
|
+
const progId = await wslDefaultBrowser();
|
|
527
|
+
const browserInfo = _windowsBrowserProgIdMap.get(progId);
|
|
528
|
+
browser = browserInfo ?? {};
|
|
529
|
+
} else {
|
|
530
|
+
browser = await defaultBrowser2();
|
|
531
|
+
}
|
|
532
|
+
if (browser.id in ids) {
|
|
533
|
+
const browserName = ids[browser.id.toLowerCase()];
|
|
534
|
+
if (app === "browserPrivate") {
|
|
535
|
+
if (browserName === "safari") {
|
|
536
|
+
throw new Error("Safari doesn't support opening in private mode via command line");
|
|
537
|
+
}
|
|
538
|
+
appArguments.push(flags[browserName]);
|
|
539
|
+
}
|
|
540
|
+
return baseOpen({
|
|
541
|
+
...options,
|
|
542
|
+
app: {
|
|
543
|
+
name: apps[browserName],
|
|
544
|
+
arguments: appArguments
|
|
545
|
+
}
|
|
546
|
+
});
|
|
547
|
+
}
|
|
548
|
+
throw new Error(`${browser.name} is not supported as a default browser`);
|
|
549
|
+
}
|
|
550
|
+
let command;
|
|
551
|
+
const cliArguments = [];
|
|
552
|
+
const childProcessOptions = {};
|
|
553
|
+
let shouldUseWindowsInWsl = false;
|
|
554
|
+
if (is_wsl_default && !isInsideContainer() && !is_in_ssh_default && !app) {
|
|
555
|
+
shouldUseWindowsInWsl = await canAccessPowerShell();
|
|
556
|
+
}
|
|
557
|
+
if (platform === "darwin") {
|
|
558
|
+
command = "open";
|
|
559
|
+
if (options.wait) {
|
|
560
|
+
cliArguments.push("--wait-apps");
|
|
561
|
+
}
|
|
562
|
+
if (options.background) {
|
|
563
|
+
cliArguments.push("--background");
|
|
564
|
+
}
|
|
565
|
+
if (options.newInstance) {
|
|
566
|
+
cliArguments.push("--new");
|
|
567
|
+
}
|
|
568
|
+
if (app) {
|
|
569
|
+
cliArguments.push("-a", app);
|
|
570
|
+
}
|
|
571
|
+
} else if (platform === "win32" || shouldUseWindowsInWsl) {
|
|
572
|
+
command = await powerShellPath2();
|
|
573
|
+
cliArguments.push(...executePowerShell.argumentsPrefix);
|
|
574
|
+
if (!is_wsl_default) {
|
|
575
|
+
childProcessOptions.windowsVerbatimArguments = true;
|
|
576
|
+
}
|
|
577
|
+
if (is_wsl_default && options.target) {
|
|
578
|
+
options.target = await convertWslPathToWindows(options.target);
|
|
579
|
+
}
|
|
580
|
+
const encodedArguments = ["$ProgressPreference = 'SilentlyContinue';", "Start"];
|
|
581
|
+
if (options.wait) {
|
|
582
|
+
encodedArguments.push("-Wait");
|
|
583
|
+
}
|
|
584
|
+
if (app) {
|
|
585
|
+
encodedArguments.push(executePowerShell.escapeArgument(app));
|
|
586
|
+
if (options.target) {
|
|
587
|
+
appArguments.push(options.target);
|
|
588
|
+
}
|
|
589
|
+
} else if (options.target) {
|
|
590
|
+
encodedArguments.push(executePowerShell.escapeArgument(options.target));
|
|
591
|
+
}
|
|
592
|
+
if (appArguments.length > 0) {
|
|
593
|
+
appArguments = appArguments.map((argument) => executePowerShell.escapeArgument(argument));
|
|
594
|
+
encodedArguments.push("-ArgumentList", appArguments.join(","));
|
|
595
|
+
}
|
|
596
|
+
options.target = executePowerShell.encodeCommand(encodedArguments.join(" "));
|
|
597
|
+
if (!options.wait) {
|
|
598
|
+
childProcessOptions.stdio = "ignore";
|
|
599
|
+
}
|
|
600
|
+
} else {
|
|
601
|
+
if (app) {
|
|
602
|
+
command = app;
|
|
603
|
+
} else {
|
|
604
|
+
const isBundled = !__dirname2 || __dirname2 === "/";
|
|
605
|
+
let exeLocalXdgOpen = false;
|
|
606
|
+
try {
|
|
607
|
+
await fs5.access(localXdgOpenPath, fsConstants2.X_OK);
|
|
608
|
+
exeLocalXdgOpen = true;
|
|
609
|
+
} catch {}
|
|
610
|
+
const useSystemXdgOpen = process8.versions.electron ?? (platform === "android" || isBundled || !exeLocalXdgOpen);
|
|
611
|
+
command = useSystemXdgOpen ? "xdg-open" : localXdgOpenPath;
|
|
612
|
+
}
|
|
613
|
+
if (appArguments.length > 0) {
|
|
614
|
+
cliArguments.push(...appArguments);
|
|
615
|
+
}
|
|
616
|
+
if (!options.wait) {
|
|
617
|
+
childProcessOptions.stdio = "ignore";
|
|
618
|
+
childProcessOptions.detached = true;
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
if (platform === "darwin" && appArguments.length > 0) {
|
|
622
|
+
cliArguments.push("--args", ...appArguments);
|
|
623
|
+
}
|
|
624
|
+
if (options.target) {
|
|
625
|
+
cliArguments.push(options.target);
|
|
626
|
+
}
|
|
627
|
+
const subprocess = childProcess3.spawn(command, cliArguments, childProcessOptions);
|
|
628
|
+
if (options.wait) {
|
|
629
|
+
return new Promise((resolve, reject) => {
|
|
630
|
+
subprocess.once("error", reject);
|
|
631
|
+
subprocess.once("close", (exitCode) => {
|
|
632
|
+
if (!options.allowNonzeroExitCode && exitCode !== 0) {
|
|
633
|
+
reject(new Error(`Exited with code ${exitCode}`));
|
|
634
|
+
return;
|
|
635
|
+
}
|
|
636
|
+
resolve(subprocess);
|
|
637
|
+
});
|
|
638
|
+
});
|
|
639
|
+
}
|
|
640
|
+
if (isFallbackAttempt) {
|
|
641
|
+
return new Promise((resolve, reject) => {
|
|
642
|
+
subprocess.once("error", reject);
|
|
643
|
+
subprocess.once("spawn", () => {
|
|
644
|
+
subprocess.once("close", (exitCode) => {
|
|
645
|
+
subprocess.off("error", reject);
|
|
646
|
+
if (exitCode !== 0) {
|
|
647
|
+
reject(new Error(`Exited with code ${exitCode}`));
|
|
648
|
+
return;
|
|
649
|
+
}
|
|
650
|
+
subprocess.unref();
|
|
651
|
+
resolve(subprocess);
|
|
652
|
+
});
|
|
653
|
+
});
|
|
654
|
+
});
|
|
655
|
+
}
|
|
656
|
+
subprocess.unref();
|
|
657
|
+
return new Promise((resolve, reject) => {
|
|
658
|
+
subprocess.once("error", reject);
|
|
659
|
+
subprocess.once("spawn", () => {
|
|
660
|
+
subprocess.off("error", reject);
|
|
661
|
+
resolve(subprocess);
|
|
662
|
+
});
|
|
663
|
+
});
|
|
664
|
+
}, open = (target, options) => {
|
|
665
|
+
if (typeof target !== "string") {
|
|
666
|
+
throw new TypeError("Expected a `target`");
|
|
667
|
+
}
|
|
668
|
+
return baseOpen({
|
|
669
|
+
...options,
|
|
670
|
+
target
|
|
671
|
+
});
|
|
672
|
+
}, openApp = (name, options) => {
|
|
673
|
+
if (typeof name !== "string" && !Array.isArray(name)) {
|
|
674
|
+
throw new TypeError("Expected a valid `name`");
|
|
675
|
+
}
|
|
676
|
+
const { arguments: appArguments = [] } = options ?? {};
|
|
677
|
+
if (appArguments !== undefined && appArguments !== null && !Array.isArray(appArguments)) {
|
|
678
|
+
throw new TypeError("Expected `appArguments` as Array type");
|
|
679
|
+
}
|
|
680
|
+
return baseOpen({
|
|
681
|
+
...options,
|
|
682
|
+
app: {
|
|
683
|
+
name,
|
|
684
|
+
arguments: appArguments
|
|
685
|
+
}
|
|
686
|
+
});
|
|
687
|
+
}, apps, open_default;
|
|
688
|
+
var init_open = __esm(() => {
|
|
689
|
+
init_wsl_utils();
|
|
690
|
+
init_powershell_utils();
|
|
691
|
+
init_default_browser();
|
|
692
|
+
init_is_inside_container();
|
|
693
|
+
init_is_in_ssh();
|
|
694
|
+
fallbackAttemptSymbol = Symbol("fallbackAttempt");
|
|
695
|
+
__dirname2 = import.meta.url ? path.dirname(fileURLToPath(import.meta.url)) : "";
|
|
696
|
+
localXdgOpenPath = path.join(__dirname2, "xdg-open");
|
|
697
|
+
({ platform, arch } = process8);
|
|
698
|
+
apps = {
|
|
699
|
+
browser: "browser",
|
|
700
|
+
browserPrivate: "browserPrivate"
|
|
701
|
+
};
|
|
702
|
+
defineLazyProperty(apps, "chrome", () => detectPlatformBinary({
|
|
703
|
+
darwin: "google chrome",
|
|
704
|
+
win32: "chrome",
|
|
705
|
+
linux: ["google-chrome", "google-chrome-stable", "chromium", "chromium-browser"]
|
|
706
|
+
}, {
|
|
707
|
+
wsl: {
|
|
708
|
+
ia32: "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe",
|
|
709
|
+
x64: ["/mnt/c/Program Files/Google/Chrome/Application/chrome.exe", "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe"]
|
|
710
|
+
}
|
|
711
|
+
}));
|
|
712
|
+
defineLazyProperty(apps, "brave", () => detectPlatformBinary({
|
|
713
|
+
darwin: "brave browser",
|
|
714
|
+
win32: "brave",
|
|
715
|
+
linux: ["brave-browser", "brave"]
|
|
716
|
+
}, {
|
|
717
|
+
wsl: {
|
|
718
|
+
ia32: "/mnt/c/Program Files (x86)/BraveSoftware/Brave-Browser/Application/brave.exe",
|
|
719
|
+
x64: ["/mnt/c/Program Files/BraveSoftware/Brave-Browser/Application/brave.exe", "/mnt/c/Program Files (x86)/BraveSoftware/Brave-Browser/Application/brave.exe"]
|
|
720
|
+
}
|
|
721
|
+
}));
|
|
722
|
+
defineLazyProperty(apps, "firefox", () => detectPlatformBinary({
|
|
723
|
+
darwin: "firefox",
|
|
724
|
+
win32: String.raw`C:\Program Files\Mozilla Firefox\firefox.exe`,
|
|
725
|
+
linux: "firefox"
|
|
726
|
+
}, {
|
|
727
|
+
wsl: "/mnt/c/Program Files/Mozilla Firefox/firefox.exe"
|
|
728
|
+
}));
|
|
729
|
+
defineLazyProperty(apps, "edge", () => detectPlatformBinary({
|
|
730
|
+
darwin: "microsoft edge",
|
|
731
|
+
win32: "msedge",
|
|
732
|
+
linux: ["microsoft-edge", "microsoft-edge-dev"]
|
|
733
|
+
}, {
|
|
734
|
+
wsl: "/mnt/c/Program Files (x86)/Microsoft/Edge/Application/msedge.exe"
|
|
735
|
+
}));
|
|
736
|
+
defineLazyProperty(apps, "safari", () => detectPlatformBinary({
|
|
737
|
+
darwin: "Safari"
|
|
738
|
+
}));
|
|
739
|
+
open_default = open;
|
|
740
|
+
});
|
|
741
|
+
|
|
742
|
+
// ../filesystem/src/node.ts
|
|
743
|
+
import { randomUUID } from "node:crypto";
|
|
744
|
+
import { existsSync } from "node:fs";
|
|
745
|
+
import * as fs6 from "node:fs/promises";
|
|
746
|
+
import * as os2 from "node:os";
|
|
747
|
+
import * as path2 from "node:path";
|
|
748
|
+
|
|
749
|
+
class NodeFileSystem {
|
|
750
|
+
path = {
|
|
751
|
+
join: path2.join,
|
|
752
|
+
resolve: path2.resolve,
|
|
753
|
+
relative: path2.relative,
|
|
754
|
+
dirname: path2.dirname,
|
|
755
|
+
isAbsolute: path2.isAbsolute,
|
|
756
|
+
basename: path2.basename
|
|
757
|
+
};
|
|
758
|
+
env = {
|
|
759
|
+
cwd: process.cwd,
|
|
760
|
+
homedir: os2.homedir,
|
|
761
|
+
tmpdir: os2.tmpdir,
|
|
762
|
+
getenv: (key) => process.env[key]
|
|
763
|
+
};
|
|
764
|
+
utils = {
|
|
765
|
+
open: async (url) => {
|
|
766
|
+
const { default: open2 } = await Promise.resolve().then(() => (init_open(), exports_open));
|
|
767
|
+
await open2(url);
|
|
768
|
+
}
|
|
769
|
+
};
|
|
770
|
+
async readFile(path3, options) {
|
|
771
|
+
try {
|
|
772
|
+
if (options) {
|
|
773
|
+
return await fs6.readFile(path3, "utf-8");
|
|
774
|
+
}
|
|
775
|
+
return await fs6.readFile(path3);
|
|
776
|
+
} catch (error) {
|
|
777
|
+
if (this.isEnoent(error))
|
|
778
|
+
return null;
|
|
779
|
+
throw error;
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
async writeFile(filePath, data) {
|
|
783
|
+
const dir = path2.dirname(filePath);
|
|
784
|
+
if (dir) {
|
|
785
|
+
await fs6.mkdir(dir, { recursive: true });
|
|
786
|
+
}
|
|
787
|
+
await fs6.writeFile(filePath, data);
|
|
788
|
+
}
|
|
789
|
+
async appendFile(filePath, data) {
|
|
790
|
+
const dir = path2.dirname(filePath);
|
|
791
|
+
if (dir) {
|
|
792
|
+
await fs6.mkdir(dir, { recursive: true });
|
|
793
|
+
}
|
|
794
|
+
await fs6.appendFile(filePath, data);
|
|
795
|
+
}
|
|
796
|
+
async readdir(dirPath) {
|
|
797
|
+
try {
|
|
798
|
+
return await fs6.readdir(dirPath);
|
|
799
|
+
} catch (error) {
|
|
800
|
+
if (this.isEnoent(error))
|
|
801
|
+
return [];
|
|
802
|
+
throw error;
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
async stat(filePath) {
|
|
806
|
+
try {
|
|
807
|
+
const stats = await fs6.stat(filePath);
|
|
808
|
+
return {
|
|
809
|
+
isFile: () => stats.isFile(),
|
|
810
|
+
isDirectory: () => stats.isDirectory(),
|
|
811
|
+
size: stats.size,
|
|
812
|
+
mtimeMs: stats.mtimeMs
|
|
813
|
+
};
|
|
814
|
+
} catch (error) {
|
|
815
|
+
if (this.isEnoent(error))
|
|
816
|
+
return null;
|
|
817
|
+
throw error;
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
async exists(filePath) {
|
|
821
|
+
return existsSync(filePath);
|
|
822
|
+
}
|
|
823
|
+
async mkdir(dirPath) {
|
|
824
|
+
await fs6.mkdir(dirPath, { recursive: true });
|
|
825
|
+
}
|
|
826
|
+
async acquireLock(lockPath) {
|
|
827
|
+
const canonicalPath = await this.canonicalizeLockTarget(lockPath);
|
|
828
|
+
const lockFile = `${canonicalPath}.lock`;
|
|
829
|
+
const ownerId = randomUUID();
|
|
830
|
+
const start = Date.now();
|
|
831
|
+
while (true) {
|
|
832
|
+
try {
|
|
833
|
+
await fs6.writeFile(lockFile, ownerId, { flag: "wx" });
|
|
834
|
+
return this.createLockRelease(lockFile, ownerId);
|
|
835
|
+
} catch (error) {
|
|
836
|
+
if (!this.hasErrnoCode(error, "EEXIST")) {
|
|
837
|
+
throw error;
|
|
838
|
+
}
|
|
839
|
+
const stats = await fs6.stat(lockFile).catch(() => null);
|
|
840
|
+
if (stats && Date.now() - stats.mtimeMs > LOCK_STALE_MS) {
|
|
841
|
+
const reclaimed = await fs6.rm(lockFile, { force: true }).then(() => true).catch(() => false);
|
|
842
|
+
if (reclaimed)
|
|
843
|
+
continue;
|
|
844
|
+
}
|
|
845
|
+
if (Date.now() - start > LOCK_MAX_WAIT_MS) {
|
|
846
|
+
throw new Error(`ELOCKED: timed out waiting for lock on ${canonicalPath}`);
|
|
847
|
+
}
|
|
848
|
+
await new Promise((resolve2) => setTimeout(resolve2, LOCK_RETRY_MIN_MS + Math.random() * LOCK_RETRY_JITTER_MS));
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
async canonicalizeLockTarget(lockPath) {
|
|
853
|
+
const absolute = path2.resolve(lockPath);
|
|
854
|
+
const fullReal = await fs6.realpath(absolute).catch(() => null);
|
|
855
|
+
if (fullReal)
|
|
856
|
+
return fullReal;
|
|
857
|
+
const parent = path2.dirname(absolute);
|
|
858
|
+
const base = path2.basename(absolute);
|
|
859
|
+
const canonicalParent = await fs6.realpath(parent).catch(() => parent);
|
|
860
|
+
return path2.join(canonicalParent, base);
|
|
861
|
+
}
|
|
862
|
+
createLockRelease(lockFile, ownerId) {
|
|
863
|
+
const heartbeatStart = Date.now();
|
|
864
|
+
let heartbeatTimer;
|
|
865
|
+
let stopped = false;
|
|
866
|
+
const stopHeartbeat = () => {
|
|
867
|
+
stopped = true;
|
|
868
|
+
if (heartbeatTimer)
|
|
869
|
+
clearTimeout(heartbeatTimer);
|
|
870
|
+
};
|
|
871
|
+
const scheduleNextHeartbeat = () => {
|
|
872
|
+
if (stopped)
|
|
873
|
+
return;
|
|
874
|
+
if (Date.now() - heartbeatStart >= LOCK_MAX_HOLD_MS) {
|
|
875
|
+
stopped = true;
|
|
876
|
+
return;
|
|
877
|
+
}
|
|
878
|
+
heartbeatTimer = setTimeout(() => {
|
|
879
|
+
runHeartbeat();
|
|
880
|
+
}, LOCK_HEARTBEAT_MS);
|
|
881
|
+
heartbeatTimer.unref?.();
|
|
882
|
+
};
|
|
883
|
+
const runHeartbeat = async () => {
|
|
884
|
+
if (stopped)
|
|
885
|
+
return;
|
|
886
|
+
const current = await fs6.readFile(lockFile, "utf-8").catch(() => null);
|
|
887
|
+
if (stopped)
|
|
888
|
+
return;
|
|
889
|
+
if (current !== ownerId) {
|
|
890
|
+
stopped = true;
|
|
891
|
+
return;
|
|
892
|
+
}
|
|
893
|
+
const now = Date.now() / 1000;
|
|
894
|
+
await fs6.utimes(lockFile, now, now).catch(() => {});
|
|
895
|
+
scheduleNextHeartbeat();
|
|
896
|
+
};
|
|
897
|
+
scheduleNextHeartbeat();
|
|
898
|
+
let released = false;
|
|
899
|
+
return async () => {
|
|
900
|
+
if (released)
|
|
901
|
+
return;
|
|
902
|
+
released = true;
|
|
903
|
+
stopHeartbeat();
|
|
904
|
+
const current = await fs6.readFile(lockFile, "utf-8").catch(() => null);
|
|
905
|
+
if (current === ownerId) {
|
|
906
|
+
await fs6.rm(lockFile, { force: true });
|
|
907
|
+
}
|
|
908
|
+
};
|
|
909
|
+
}
|
|
910
|
+
async rm(filePath) {
|
|
911
|
+
await fs6.rm(filePath, { recursive: true, force: true });
|
|
912
|
+
}
|
|
913
|
+
async rename(oldPath, newPath) {
|
|
914
|
+
await fs6.rename(oldPath, newPath);
|
|
915
|
+
}
|
|
916
|
+
async realpath(filePath) {
|
|
917
|
+
try {
|
|
918
|
+
return await fs6.realpath(filePath);
|
|
919
|
+
} catch (error) {
|
|
920
|
+
if (this.isEnoent(error))
|
|
921
|
+
return filePath;
|
|
922
|
+
throw error;
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
async getTempDir() {
|
|
926
|
+
return await fs6.mkdtemp(path2.join(os2.tmpdir(), "uipath-fs-"));
|
|
927
|
+
}
|
|
928
|
+
async copyDirectory(sourcePath, destPath) {
|
|
929
|
+
const sourceStats = await this.stat(sourcePath);
|
|
930
|
+
if (!sourceStats) {
|
|
931
|
+
throw new Error(`Source directory does not exist: ${sourcePath}`);
|
|
932
|
+
}
|
|
933
|
+
if (!sourceStats.isDirectory()) {
|
|
934
|
+
throw new Error(`Source path is not a directory: ${sourcePath}`);
|
|
935
|
+
}
|
|
936
|
+
await this.mkdir(destPath);
|
|
937
|
+
const entries = await this.readdir(sourcePath);
|
|
938
|
+
for (const entry of entries) {
|
|
939
|
+
const srcEntry = path2.join(sourcePath, entry);
|
|
940
|
+
const destEntry = path2.join(destPath, entry);
|
|
941
|
+
const entryStats = await this.stat(srcEntry);
|
|
942
|
+
if (!entryStats)
|
|
943
|
+
continue;
|
|
944
|
+
if (entryStats.isDirectory()) {
|
|
945
|
+
await this.copyDirectory(srcEntry, destEntry);
|
|
946
|
+
} else if (entryStats.isFile()) {
|
|
947
|
+
const content = await this.readFile(srcEntry);
|
|
948
|
+
if (content !== null) {
|
|
949
|
+
await this.writeFile(destEntry, content);
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
isEnoent(error) {
|
|
955
|
+
return this.hasErrnoCode(error, "ENOENT");
|
|
956
|
+
}
|
|
957
|
+
hasErrnoCode(error, code) {
|
|
958
|
+
return typeof error === "object" && error !== null && "code" in error && error.code === code;
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
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;
|
|
962
|
+
var init_node = () => {};
|
|
963
|
+
// ../filesystem/src/index.ts
|
|
964
|
+
var fsInstance, getFileSystem = () => fsInstance;
|
|
965
|
+
var init_src = __esm(() => {
|
|
966
|
+
init_node();
|
|
967
|
+
init_node();
|
|
968
|
+
fsInstance = new NodeFileSystem;
|
|
969
|
+
});
|
|
970
|
+
|
|
971
|
+
// ../auth/src/config.ts
|
|
972
|
+
init_constants();
|
|
973
|
+
var DEFAULT_CLIENT_ID = "36dea5b8-e8bb-423d-8e7b-c808df8f1c00";
|
|
974
|
+
var AUTH_FILE_CONFIG_KEY = Symbol.for("@uipath/auth/AuthFileConfig");
|
|
975
|
+
var globalSlot = globalThis;
|
|
976
|
+
var getAuthFileConfig = () => globalSlot[AUTH_FILE_CONFIG_KEY] ?? {};
|
|
977
|
+
|
|
978
|
+
class InvalidBaseUrlError extends Error {
|
|
979
|
+
url;
|
|
980
|
+
reason;
|
|
981
|
+
constructor(url, reason) {
|
|
982
|
+
super(`Invalid base URL: "${url}"
|
|
983
|
+
` + `Reason: ${reason}
|
|
984
|
+
|
|
985
|
+
` + `Expected format: an https:// URL, e.g. https://cloud.uipath.com (commercial), https://govcloud.uipath.us (Public Sector), or your Automation Suite host (https://<your-host>).
|
|
986
|
+
` + `You can specify the URL via:
|
|
987
|
+
` + ` • --authority flag
|
|
988
|
+
` + ` • UIPATH_URL environment variable
|
|
989
|
+
` + ` • auth.authority in config file`);
|
|
990
|
+
this.url = url;
|
|
991
|
+
this.reason = reason;
|
|
992
|
+
this.name = "InvalidBaseUrlError";
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
var DEFAULT_SCOPES = ["openid", "profile", "offline_access"];
|
|
996
|
+
var normalizeAndValidateBaseUrl = (rawUrl) => {
|
|
997
|
+
let baseUrl = rawUrl;
|
|
998
|
+
if (baseUrl.endsWith("/identity_/")) {
|
|
999
|
+
baseUrl = baseUrl.slice(0, -11);
|
|
1000
|
+
} else if (baseUrl.endsWith("/identity_")) {
|
|
1001
|
+
baseUrl = baseUrl.slice(0, -10);
|
|
1002
|
+
}
|
|
1003
|
+
while (baseUrl.endsWith("/")) {
|
|
1004
|
+
baseUrl = baseUrl.slice(0, -1);
|
|
1005
|
+
}
|
|
1006
|
+
const resolvedBaseUrl = baseUrl;
|
|
1007
|
+
const [urlError, url] = catchError(() => new URL(resolvedBaseUrl));
|
|
1008
|
+
if (urlError) {
|
|
1009
|
+
throw new InvalidBaseUrlError(baseUrl, `Malformed URL. ${urlError instanceof Error ? urlError.message : "Unknown error"}`);
|
|
1010
|
+
}
|
|
1011
|
+
if (url.protocol !== "https:") {
|
|
1012
|
+
throw new InvalidBaseUrlError(baseUrl, `Authority must use https:// scheme, got ${url.protocol}//. OIDC token exchange requires TLS end-to-end.`);
|
|
1013
|
+
}
|
|
1014
|
+
return url.pathname.length > 1 ? url.origin : baseUrl;
|
|
1015
|
+
};
|
|
1016
|
+
var resolveScopes = (isExternalAppAuth, customScopes, fileScopes) => {
|
|
1017
|
+
const requestedScopes = customScopes?.length ? customScopes : fileScopes ?? [];
|
|
1018
|
+
if (isExternalAppAuth)
|
|
1019
|
+
return requestedScopes;
|
|
1020
|
+
return [...new Set([...DEFAULT_SCOPES, ...requestedScopes])];
|
|
1021
|
+
};
|
|
1022
|
+
var resolveConfigAsync = async ({
|
|
1023
|
+
customAuthority,
|
|
1024
|
+
customClientId,
|
|
1025
|
+
customClientSecret,
|
|
1026
|
+
customClientAssertion,
|
|
1027
|
+
customScopes
|
|
1028
|
+
} = {}) => {
|
|
1029
|
+
const fileAuth = getAuthFileConfig();
|
|
1030
|
+
let baseUrl = customAuthority;
|
|
1031
|
+
if (!baseUrl) {
|
|
1032
|
+
baseUrl = process.env.UIPATH_URL;
|
|
1033
|
+
}
|
|
1034
|
+
if (!baseUrl && fileAuth.authority) {
|
|
1035
|
+
baseUrl = fileAuth.authority;
|
|
1036
|
+
}
|
|
1037
|
+
if (!baseUrl) {
|
|
1038
|
+
baseUrl = DEFAULT_BASE_URL;
|
|
1039
|
+
}
|
|
1040
|
+
baseUrl = normalizeAndValidateBaseUrl(baseUrl);
|
|
1041
|
+
let clientId = customClientId;
|
|
1042
|
+
if (!clientId && fileAuth.clientId) {
|
|
1043
|
+
clientId = fileAuth.clientId;
|
|
1044
|
+
}
|
|
1045
|
+
if (!clientId) {
|
|
1046
|
+
clientId = DEFAULT_CLIENT_ID;
|
|
1047
|
+
}
|
|
1048
|
+
let clientSecret = customClientSecret;
|
|
1049
|
+
if (!clientSecret && fileAuth.clientSecret) {
|
|
1050
|
+
clientSecret = fileAuth.clientSecret;
|
|
1051
|
+
}
|
|
1052
|
+
const isExternalAppAuth = clientId !== DEFAULT_CLIENT_ID && (Boolean(clientSecret) || Boolean(customClientAssertion));
|
|
1053
|
+
const scopes = resolveScopes(isExternalAppAuth, customScopes, fileAuth.scopes);
|
|
1054
|
+
return {
|
|
1055
|
+
clientId,
|
|
1056
|
+
clientSecret,
|
|
1057
|
+
scopes,
|
|
1058
|
+
baseUrl,
|
|
1059
|
+
authorizationEndpoint: `${baseUrl}/identity_/connect/authorize`,
|
|
1060
|
+
tokenEndpoint: `${baseUrl}/identity_/connect/token`
|
|
1061
|
+
};
|
|
1062
|
+
};
|
|
1063
|
+
|
|
1064
|
+
// ../auth/src/index.ts
|
|
1065
|
+
init_constants();
|
|
1066
|
+
// ../auth/src/loginStatus.ts
|
|
1067
|
+
init_src();
|
|
1068
|
+
|
|
1069
|
+
// ../auth/src/authProfile.ts
|
|
1070
|
+
init_src();
|
|
1071
|
+
init_constants();
|
|
1072
|
+
var DEFAULT_AUTH_PROFILE = "default";
|
|
1073
|
+
var PROFILE_DIR = "profiles";
|
|
1074
|
+
var PROFILE_NAME_RE = /^[A-Za-z0-9._-]+$/;
|
|
1075
|
+
var ACTIVE_AUTH_PROFILE_KEY = Symbol.for("@uipath/auth/ActiveAuthProfile");
|
|
1076
|
+
var AUTH_PROFILE_STORAGE_KEY = Symbol.for("@uipath/auth/ProfileStorage");
|
|
1077
|
+
var globalSlot2 = globalThis;
|
|
1078
|
+
function isAuthProfileStorage(value) {
|
|
1079
|
+
return value !== null && typeof value === "object" && "getStore" in value && "run" in value;
|
|
1080
|
+
}
|
|
1081
|
+
function createProfileStorage() {
|
|
1082
|
+
const [error, mod] = catchError(() => __require("node:async_hooks"));
|
|
1083
|
+
if (error || typeof mod?.AsyncLocalStorage !== "function") {
|
|
1084
|
+
return {
|
|
1085
|
+
getStore: () => {
|
|
1086
|
+
return;
|
|
1087
|
+
},
|
|
1088
|
+
run: (_store, fn) => fn()
|
|
1089
|
+
};
|
|
1090
|
+
}
|
|
1091
|
+
return new mod.AsyncLocalStorage;
|
|
1092
|
+
}
|
|
1093
|
+
function getProfileStorage() {
|
|
1094
|
+
const existing = globalSlot2[AUTH_PROFILE_STORAGE_KEY];
|
|
1095
|
+
if (isAuthProfileStorage(existing)) {
|
|
1096
|
+
return existing;
|
|
1097
|
+
}
|
|
1098
|
+
const storage = createProfileStorage();
|
|
1099
|
+
globalSlot2[AUTH_PROFILE_STORAGE_KEY] = storage;
|
|
1100
|
+
return storage;
|
|
1101
|
+
}
|
|
1102
|
+
var profileStorage = getProfileStorage();
|
|
1103
|
+
|
|
1104
|
+
class AuthProfileValidationError extends Error {
|
|
1105
|
+
constructor(message) {
|
|
1106
|
+
super(message);
|
|
1107
|
+
this.name = "AuthProfileValidationError";
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
function normalizeAuthProfileName(profile) {
|
|
1111
|
+
if (profile === undefined || profile === DEFAULT_AUTH_PROFILE) {
|
|
1112
|
+
return;
|
|
1113
|
+
}
|
|
1114
|
+
if (profile.length === 0 || profile === "." || profile === ".." || !PROFILE_NAME_RE.test(profile)) {
|
|
1115
|
+
throw new AuthProfileValidationError(`Invalid profile name "${profile}". Profile names may contain only letters, numbers, '.', '_', and '-'.`);
|
|
1116
|
+
}
|
|
1117
|
+
return profile;
|
|
1118
|
+
}
|
|
1119
|
+
function getActiveAuthProfile() {
|
|
1120
|
+
const scopedState = profileStorage.getStore();
|
|
1121
|
+
if (scopedState !== undefined) {
|
|
1122
|
+
return scopedState.profile;
|
|
1123
|
+
}
|
|
1124
|
+
return globalSlot2[ACTIVE_AUTH_PROFILE_KEY]?.profile;
|
|
1125
|
+
}
|
|
1126
|
+
function resolveAuthProfileFilePath(profile) {
|
|
1127
|
+
const normalized = normalizeAuthProfileName(profile);
|
|
1128
|
+
if (normalized === undefined) {
|
|
1129
|
+
throw new AuthProfileValidationError(`"${DEFAULT_AUTH_PROFILE}" is the built-in profile and does not have a profile file path.`);
|
|
1130
|
+
}
|
|
1131
|
+
const fs7 = getFileSystem();
|
|
1132
|
+
return fs7.path.join(fs7.env.homedir(), UIPATH_HOME_DIR, PROFILE_DIR, normalized, AUTH_FILENAME);
|
|
1133
|
+
}
|
|
1134
|
+
function getActiveAuthProfileFilePath() {
|
|
1135
|
+
const profile = getActiveAuthProfile();
|
|
1136
|
+
return profile ? resolveAuthProfileFilePath(profile) : undefined;
|
|
1137
|
+
}
|
|
1138
|
+
// ../auth/src/utils/jwt.ts
|
|
1139
|
+
class InvalidIssuerError extends Error {
|
|
1140
|
+
expected;
|
|
1141
|
+
actual;
|
|
1142
|
+
constructor(expected, actual) {
|
|
1143
|
+
const actualText = actual ?? "<missing>";
|
|
1144
|
+
super(`Token issuer does not match the authority used to log in.
|
|
1145
|
+
` + `Expected: ${expected}
|
|
1146
|
+
` + `Actual: ${actualText}
|
|
1147
|
+
|
|
1148
|
+
` + `The identity server that issued this token is not the one ` + `you pointed --authority at. Refusing to save credentials.`);
|
|
1149
|
+
this.expected = expected;
|
|
1150
|
+
this.actual = actual;
|
|
1151
|
+
this.name = "InvalidIssuerError";
|
|
1152
|
+
}
|
|
1153
|
+
}
|
|
1154
|
+
var parseJWT = (token) => {
|
|
1155
|
+
try {
|
|
1156
|
+
const parts = token.split(".");
|
|
1157
|
+
const base64Url = parts[1];
|
|
1158
|
+
if (!base64Url) {
|
|
1159
|
+
throw new Error("Invalid JWT token format - missing payload section");
|
|
1160
|
+
}
|
|
1161
|
+
const base64 = base64Url.replace(/-/g, "+").replace(/_/g, "/");
|
|
1162
|
+
let decodedString;
|
|
1163
|
+
if (isBrowser() && typeof atob !== "undefined") {
|
|
1164
|
+
decodedString = atob(base64);
|
|
1165
|
+
} else {
|
|
1166
|
+
decodedString = Buffer.from(base64, "base64").toString();
|
|
1167
|
+
}
|
|
1168
|
+
const jsonPayload = decodeURIComponent(decodedString.split("").map((c) => `%${`00${c.charCodeAt(0).toString(16)}`.slice(-2)}`).join(""));
|
|
1169
|
+
const parsed = JSON.parse(jsonPayload);
|
|
1170
|
+
return parsed;
|
|
1171
|
+
} catch (error) {
|
|
1172
|
+
throw new Error(`Failed to parse JWT: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
1173
|
+
}
|
|
1174
|
+
};
|
|
1175
|
+
var assertIssuerMatchesAuthority = (token, authority) => {
|
|
1176
|
+
let payload;
|
|
1177
|
+
try {
|
|
1178
|
+
payload = parseJWT(token);
|
|
1179
|
+
} catch (error) {
|
|
1180
|
+
throw new InvalidIssuerError(`${authority.replace(/\/+$/, "")}/identity_`, `<unparseable: ${error instanceof Error ? error.message : "unknown error"}>`);
|
|
1181
|
+
}
|
|
1182
|
+
const stripTrailingSlash = (s) => s.replace(/\/+$/, "");
|
|
1183
|
+
const expected = `${stripTrailingSlash(authority)}/identity_`;
|
|
1184
|
+
const actual = typeof payload.iss === "string" ? stripTrailingSlash(payload.iss) : undefined;
|
|
1185
|
+
if (actual !== expected) {
|
|
1186
|
+
throw new InvalidIssuerError(expected, payload.iss);
|
|
1187
|
+
}
|
|
1188
|
+
};
|
|
1189
|
+
var getTokenExpiration = (accessToken) => {
|
|
1190
|
+
try {
|
|
1191
|
+
const parts = accessToken.split(".");
|
|
1192
|
+
if (parts.length !== 3) {
|
|
1193
|
+
return;
|
|
1194
|
+
}
|
|
1195
|
+
const payload = parts[1];
|
|
1196
|
+
const base64 = payload.replace(/-/g, "+").replace(/_/g, "/");
|
|
1197
|
+
const padded = base64 + "=".repeat((4 - base64.length % 4) % 4);
|
|
1198
|
+
const decoded = atob(padded);
|
|
1199
|
+
const claims = JSON.parse(decoded);
|
|
1200
|
+
if (typeof claims.exp !== "number") {
|
|
1201
|
+
return;
|
|
1202
|
+
}
|
|
1203
|
+
return new Date(claims.exp * 1000);
|
|
1204
|
+
} catch {
|
|
1205
|
+
return;
|
|
1206
|
+
}
|
|
1207
|
+
};
|
|
1208
|
+
|
|
1209
|
+
// ../auth/src/sessionIdentity.ts
|
|
1210
|
+
var parseAuthFlow = (value) => value === "authorization_code" || value === "client_credentials" || value === "federated_credentials" ? value : undefined;
|
|
1211
|
+
var decodeClaims = (accessToken) => {
|
|
1212
|
+
const [error, claims] = catchError(() => parseJWT(accessToken));
|
|
1213
|
+
return error ? undefined : claims;
|
|
1214
|
+
};
|
|
1215
|
+
var asString = (value) => typeof value === "string" && value.length > 0 ? value : undefined;
|
|
1216
|
+
var resolveIdentityType = (claims, authFlow, email) => {
|
|
1217
|
+
const subType = asString(claims?.sub_type);
|
|
1218
|
+
if (subType) {
|
|
1219
|
+
return subType.startsWith("service") ? "Application" : "User";
|
|
1220
|
+
}
|
|
1221
|
+
if (authFlow) {
|
|
1222
|
+
return authFlow === "authorization_code" ? "User" : "Application";
|
|
1223
|
+
}
|
|
1224
|
+
if (email)
|
|
1225
|
+
return "User";
|
|
1226
|
+
if (asString(claims?.client_id) && !asString(claims?.sub)) {
|
|
1227
|
+
return "Application";
|
|
1228
|
+
}
|
|
1229
|
+
return;
|
|
1230
|
+
};
|
|
1231
|
+
var looksLikeEmail = (value) => value?.includes("@") ?? false;
|
|
1232
|
+
var pickEmail = (claims) => {
|
|
1233
|
+
for (const candidate of [claims?.email, claims?.preferred_username]) {
|
|
1234
|
+
const value = asString(candidate);
|
|
1235
|
+
if (looksLikeEmail(value))
|
|
1236
|
+
return value;
|
|
1237
|
+
}
|
|
1238
|
+
return;
|
|
1239
|
+
};
|
|
1240
|
+
var pickName = (claims) => {
|
|
1241
|
+
const username = asString(claims?.preferred_username);
|
|
1242
|
+
return asString(claims?.name) ?? (looksLikeEmail(username) ? undefined : username);
|
|
1243
|
+
};
|
|
1244
|
+
var resolveSessionIdentity = (accessToken, authFlow) => {
|
|
1245
|
+
const claims = accessToken ? decodeClaims(accessToken) : undefined;
|
|
1246
|
+
const email = pickEmail(claims);
|
|
1247
|
+
const type = resolveIdentityType(claims, authFlow, email);
|
|
1248
|
+
if (!type)
|
|
1249
|
+
return;
|
|
1250
|
+
const identity = { type };
|
|
1251
|
+
if (authFlow)
|
|
1252
|
+
identity.authFlow = authFlow;
|
|
1253
|
+
if (type === "User") {
|
|
1254
|
+
const userId = asString(claims?.sub);
|
|
1255
|
+
if (userId)
|
|
1256
|
+
identity.userId = userId;
|
|
1257
|
+
if (email)
|
|
1258
|
+
identity.userEmail = email;
|
|
1259
|
+
const name = pickName(claims);
|
|
1260
|
+
if (name)
|
|
1261
|
+
identity.userName = name;
|
|
1262
|
+
return identity;
|
|
1263
|
+
}
|
|
1264
|
+
const clientId = asString(claims?.client_id);
|
|
1265
|
+
if (clientId)
|
|
1266
|
+
identity.clientId = clientId;
|
|
1267
|
+
return identity;
|
|
1268
|
+
};
|
|
1269
|
+
|
|
1270
|
+
// ../auth/src/envAuth.ts
|
|
1271
|
+
var ENV_AUTH_ENABLE_VAR = "UIPATH_CLI_ENABLE_ENV_AUTH";
|
|
1272
|
+
var ENFORCE_ROBOT_AUTH_VAR = "UIPATH_CLI_ENFORCE_ROBOT_AUTH";
|
|
1273
|
+
var ENV_AUTH_VARS = {
|
|
1274
|
+
token: "UIPATH_CLI_AUTH_TOKEN",
|
|
1275
|
+
organizationName: "UIPATH_CLI_ORGANIZATION_NAME",
|
|
1276
|
+
organizationId: "UIPATH_CLI_ORGANIZATION_ID",
|
|
1277
|
+
tenantName: "UIPATH_CLI_TENANT_NAME",
|
|
1278
|
+
tenantId: "UIPATH_CLI_TENANT_ID"
|
|
1279
|
+
};
|
|
1280
|
+
|
|
1281
|
+
class EnvAuthConfigError extends Error {
|
|
1282
|
+
constructor(message) {
|
|
1283
|
+
super(message);
|
|
1284
|
+
this.name = "EnvAuthConfigError";
|
|
1285
|
+
}
|
|
1286
|
+
}
|
|
1287
|
+
var isEnvAuthEnabled = () => process.env[ENV_AUTH_ENABLE_VAR] === "true";
|
|
1288
|
+
var isRobotAuthEnforced = () => process.env[ENFORCE_ROBOT_AUTH_VAR] === "true";
|
|
1289
|
+
var requireEnv = (name) => {
|
|
1290
|
+
const value = process.env[name];
|
|
1291
|
+
if (!value) {
|
|
1292
|
+
throw new EnvAuthConfigError(`${ENV_AUTH_ENABLE_VAR}=true but ${name} is not set. ` + `Set ${name} to enable env-var authentication.`);
|
|
1293
|
+
}
|
|
1294
|
+
return value;
|
|
1295
|
+
};
|
|
1296
|
+
var readAuthFromEnv = () => {
|
|
1297
|
+
const accessToken = requireEnv(ENV_AUTH_VARS.token);
|
|
1298
|
+
const organizationName = requireEnv(ENV_AUTH_VARS.organizationName);
|
|
1299
|
+
const organizationId = requireEnv(ENV_AUTH_VARS.organizationId);
|
|
1300
|
+
const tenantName = requireEnv(ENV_AUTH_VARS.tenantName);
|
|
1301
|
+
const tenantId = requireEnv(ENV_AUTH_VARS.tenantId);
|
|
1302
|
+
const [parseError, payload] = catchError(() => parseJWT(accessToken));
|
|
1303
|
+
if (parseError) {
|
|
1304
|
+
throw new EnvAuthConfigError(`${ENV_AUTH_VARS.token} is not a valid JWT: ` + `${parseError instanceof Error ? parseError.message : String(parseError)}`);
|
|
1305
|
+
}
|
|
1306
|
+
const iss = payload.iss;
|
|
1307
|
+
if (typeof iss !== "string" || iss.length === 0) {
|
|
1308
|
+
throw new EnvAuthConfigError(`${ENV_AUTH_VARS.token} has no 'iss' claim; cannot determine ` + `the UiPath server. Ensure the token was issued by a UiPath identity server.`);
|
|
1309
|
+
}
|
|
1310
|
+
const [baseUrlError, baseUrl] = catchError(() => normalizeAndValidateBaseUrl(iss));
|
|
1311
|
+
if (baseUrlError) {
|
|
1312
|
+
if (baseUrlError instanceof InvalidBaseUrlError) {
|
|
1313
|
+
throw baseUrlError;
|
|
1314
|
+
}
|
|
1315
|
+
throw new EnvAuthConfigError(`Failed to derive server URL from token 'iss' claim: ` + `${baseUrlError instanceof Error ? baseUrlError.message : String(baseUrlError)}`);
|
|
1316
|
+
}
|
|
1317
|
+
const expiration = getTokenExpiration(accessToken);
|
|
1318
|
+
const loginStatus = expiration && expiration <= new Date ? "Expired" : "Logged in";
|
|
1319
|
+
const identity = resolveSessionIdentity(accessToken);
|
|
1320
|
+
return {
|
|
1321
|
+
loginStatus,
|
|
1322
|
+
accessToken,
|
|
1323
|
+
baseUrl,
|
|
1324
|
+
organizationName,
|
|
1325
|
+
organizationId,
|
|
1326
|
+
tenantName,
|
|
1327
|
+
tenantId,
|
|
1328
|
+
expiration,
|
|
1329
|
+
source: "env-vars" /* EnvironmentVariables */,
|
|
1330
|
+
...identity ? { identity } : {}
|
|
1331
|
+
};
|
|
1332
|
+
};
|
|
1333
|
+
|
|
1334
|
+
// ../auth/src/refreshCircuitBreaker.ts
|
|
1335
|
+
init_src();
|
|
1336
|
+
var BREAKER_SUFFIX = ".refresh-state";
|
|
1337
|
+
var BACKOFF_BASE_MS = 60000;
|
|
1338
|
+
var BACKOFF_CAP_MS = 60 * 60 * 1000;
|
|
1339
|
+
var SURFACE_WINDOW_MS = 60 * 60 * 1000;
|
|
1340
|
+
async function refreshTokenFingerprint(refreshToken) {
|
|
1341
|
+
const bytes = new TextEncoder().encode(refreshToken);
|
|
1342
|
+
if (globalThis.crypto?.subtle) {
|
|
1343
|
+
const digest = await globalThis.crypto.subtle.digest("SHA-256", bytes);
|
|
1344
|
+
return Array.from(new Uint8Array(digest), (b) => b.toString(16).padStart(2, "0")).join("").slice(0, 16);
|
|
1345
|
+
}
|
|
1346
|
+
const { createHash } = await import("node:crypto");
|
|
1347
|
+
return createHash("sha256").update(refreshToken).digest("hex").slice(0, 16);
|
|
1348
|
+
}
|
|
1349
|
+
function breakerPathFor(authPath) {
|
|
1350
|
+
return `${authPath}${BREAKER_SUFFIX}`;
|
|
1351
|
+
}
|
|
1352
|
+
async function loadRefreshBreaker(authPath) {
|
|
1353
|
+
const fs7 = getFileSystem();
|
|
1354
|
+
try {
|
|
1355
|
+
const content = await fs7.readFile(breakerPathFor(authPath), "utf-8");
|
|
1356
|
+
if (!content)
|
|
1357
|
+
return {};
|
|
1358
|
+
const parsed = JSON.parse(content);
|
|
1359
|
+
return parsed && typeof parsed === "object" ? parsed : {};
|
|
1360
|
+
} catch {
|
|
1361
|
+
return {};
|
|
1362
|
+
}
|
|
1363
|
+
}
|
|
1364
|
+
async function saveRefreshBreaker(authPath, state) {
|
|
1365
|
+
try {
|
|
1366
|
+
const fs7 = getFileSystem();
|
|
1367
|
+
const path3 = breakerPathFor(authPath);
|
|
1368
|
+
await fs7.mkdir(fs7.path.dirname(path3));
|
|
1369
|
+
const tempPath = `${path3}.tmp`;
|
|
1370
|
+
await fs7.writeFile(tempPath, JSON.stringify(state));
|
|
1371
|
+
await fs7.rename(tempPath, path3);
|
|
1372
|
+
} catch {}
|
|
1373
|
+
}
|
|
1374
|
+
async function clearRefreshBreaker(authPath) {
|
|
1375
|
+
const fs7 = getFileSystem();
|
|
1376
|
+
const path3 = breakerPathFor(authPath);
|
|
1377
|
+
try {
|
|
1378
|
+
if (await fs7.exists(path3)) {
|
|
1379
|
+
await fs7.rm(path3);
|
|
1380
|
+
}
|
|
1381
|
+
} catch {}
|
|
1382
|
+
}
|
|
1383
|
+
function nextBackoffMs(attempts) {
|
|
1384
|
+
const shift = Math.max(0, attempts - 1);
|
|
1385
|
+
return Math.min(BACKOFF_BASE_MS * 2 ** shift, BACKOFF_CAP_MS);
|
|
1386
|
+
}
|
|
1387
|
+
function shouldSurface(state, nowMs) {
|
|
1388
|
+
if (state.lastSurfacedAtMs === undefined)
|
|
1389
|
+
return true;
|
|
1390
|
+
return nowMs - state.lastSurfacedAtMs >= SURFACE_WINDOW_MS;
|
|
1391
|
+
}
|
|
1392
|
+
|
|
1393
|
+
// ../auth/src/robotClientFallback.ts
|
|
1394
|
+
init_src();
|
|
1395
|
+
var DEFAULT_TIMEOUT_MS = 1000;
|
|
1396
|
+
var CLOSE_TIMEOUT_MS = 500;
|
|
1397
|
+
var ROBOT_USER_SERVICES_PIPE = "UiPathUserServices";
|
|
1398
|
+
var ROBOT_USER_SERVICES_ALTERNATE_PIPE = `${ROBOT_USER_SERVICES_PIPE}Alternate`;
|
|
1399
|
+
var PIPE_NAME_MAX_LENGTH = 103;
|
|
1400
|
+
var getRobotIpcPipeNames = async () => {
|
|
1401
|
+
const fs7 = getFileSystem();
|
|
1402
|
+
const username = fs7.env.getenv("USER") ?? fs7.env.getenv("USERNAME");
|
|
1403
|
+
if (!username) {
|
|
1404
|
+
throw new Error("Unable to determine current username");
|
|
1405
|
+
}
|
|
1406
|
+
const tempPath = fs7.env.getenv("TMPDIR") ?? "/tmp/";
|
|
1407
|
+
return [ROBOT_USER_SERVICES_PIPE, ROBOT_USER_SERVICES_ALTERNATE_PIPE].map((baseName) => fs7.path.join(tempPath, `${baseName}_${username}`).substring(0, PIPE_NAME_MAX_LENGTH));
|
|
1408
|
+
};
|
|
1409
|
+
var defaultIsRobotIpcAvailable = async () => {
|
|
1410
|
+
if (process.platform === "win32") {
|
|
1411
|
+
return true;
|
|
1412
|
+
}
|
|
1413
|
+
const [pipeNamesError, pipeNames] = await catchError(getRobotIpcPipeNames());
|
|
1414
|
+
if (pipeNamesError || !pipeNames) {
|
|
1415
|
+
return false;
|
|
1416
|
+
}
|
|
1417
|
+
const fs7 = getFileSystem();
|
|
1418
|
+
for (const pipeName of pipeNames) {
|
|
1419
|
+
const [existsError, exists] = await catchError(fs7.exists(pipeName));
|
|
1420
|
+
if (!existsError && exists === true) {
|
|
1421
|
+
return true;
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
return false;
|
|
1425
|
+
};
|
|
1426
|
+
var withTimeout = (promise, timeoutMs) => new Promise((resolve2, reject) => {
|
|
1427
|
+
const timer = setTimeout(() => reject(new Error(`Robot IPC call timed out after ${timeoutMs}ms`)), timeoutMs);
|
|
1428
|
+
promise.then((value) => {
|
|
1429
|
+
clearTimeout(timer);
|
|
1430
|
+
resolve2(value);
|
|
1431
|
+
}, (error) => {
|
|
1432
|
+
clearTimeout(timer);
|
|
1433
|
+
reject(error);
|
|
1434
|
+
});
|
|
1435
|
+
});
|
|
1436
|
+
var parseResourceUrl = (url) => {
|
|
1437
|
+
const [error, parsed] = catchError(() => new URL(url));
|
|
1438
|
+
if (error || !parsed)
|
|
1439
|
+
return;
|
|
1440
|
+
const segments = parsed.pathname.split("/").filter(Boolean);
|
|
1441
|
+
return {
|
|
1442
|
+
baseUrl: parsed.origin,
|
|
1443
|
+
organizationName: segments[0],
|
|
1444
|
+
tenantName: segments[1]
|
|
1445
|
+
};
|
|
1446
|
+
};
|
|
1447
|
+
var ROBOT_CLIENT_LOADER_KEY = Symbol.for("@uipath/auth/RobotClientLoader");
|
|
1448
|
+
var getRegisteredRobotClientLoader = () => {
|
|
1449
|
+
const loader = globalThis[ROBOT_CLIENT_LOADER_KEY];
|
|
1450
|
+
return typeof loader === "function" ? loader : undefined;
|
|
1451
|
+
};
|
|
1452
|
+
var defaultLoadModule = async () => {
|
|
1453
|
+
const hostLoader = getRegisteredRobotClientLoader();
|
|
1454
|
+
if (!hostLoader) {
|
|
1455
|
+
return;
|
|
1456
|
+
}
|
|
1457
|
+
const [error, mod] = await catchError(() => hostLoader());
|
|
1458
|
+
if (error || !mod) {
|
|
1459
|
+
return;
|
|
1460
|
+
}
|
|
1461
|
+
return mod;
|
|
1462
|
+
};
|
|
1463
|
+
var tryRobotClientFallback = async (options = {}) => {
|
|
1464
|
+
if (isBrowser())
|
|
1465
|
+
return;
|
|
1466
|
+
if (!options.force) {
|
|
1467
|
+
if (process.env.CI || process.env.GITHUB_ACTIONS) {
|
|
1468
|
+
return;
|
|
1469
|
+
}
|
|
1470
|
+
if (process.env.UIPATH_URL) {
|
|
1471
|
+
return;
|
|
1472
|
+
}
|
|
1473
|
+
}
|
|
1474
|
+
const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
1475
|
+
const isRobotIpcAvailable = options.isRobotIpcAvailable ?? defaultIsRobotIpcAvailable;
|
|
1476
|
+
const loadModule = options.loadModule ?? defaultLoadModule;
|
|
1477
|
+
if (!await isRobotIpcAvailable()) {
|
|
1478
|
+
return;
|
|
1479
|
+
}
|
|
1480
|
+
const mod = await loadModule();
|
|
1481
|
+
if (!mod)
|
|
1482
|
+
return;
|
|
1483
|
+
const [ctorError, proxy] = catchError(() => new mod.RobotProxyConstructor);
|
|
1484
|
+
if (ctorError || !proxy) {
|
|
1485
|
+
return;
|
|
1486
|
+
}
|
|
1487
|
+
try {
|
|
1488
|
+
const enabled = await withTimeout(proxy.interactiveConnectFlow.IsEnabled(), timeoutMs);
|
|
1489
|
+
if (!enabled) {
|
|
1490
|
+
return;
|
|
1491
|
+
}
|
|
1492
|
+
const [resourceUrl, accessToken] = await Promise.all([
|
|
1493
|
+
withTimeout(proxy.accessProvider.GetResourceUrl("Orchestrator"), timeoutMs),
|
|
1494
|
+
withTimeout(proxy.accessProvider.GetAccessToken("Orchestrator", false), timeoutMs)
|
|
1495
|
+
]);
|
|
1496
|
+
if (!accessToken) {
|
|
1497
|
+
return;
|
|
1498
|
+
}
|
|
1499
|
+
const parsedUrl = parseResourceUrl(resourceUrl);
|
|
1500
|
+
if (!parsedUrl) {
|
|
1501
|
+
return;
|
|
1502
|
+
}
|
|
1503
|
+
let organizationIdFromToken;
|
|
1504
|
+
let tenantIdFromToken;
|
|
1505
|
+
let issuerFromToken;
|
|
1506
|
+
const [jwtError, claims] = catchError(() => parseJWT(accessToken));
|
|
1507
|
+
if (!jwtError && claims) {
|
|
1508
|
+
const rawOrgId = claims.prtId ?? claims.organizationId ?? claims.prt_id;
|
|
1509
|
+
if (typeof rawOrgId === "string" && rawOrgId.length > 0) {
|
|
1510
|
+
organizationIdFromToken = rawOrgId;
|
|
1511
|
+
}
|
|
1512
|
+
const tenantClaim = claims.tenantId ?? claims.tenant_id;
|
|
1513
|
+
if (typeof tenantClaim === "string" && tenantClaim.length > 0) {
|
|
1514
|
+
tenantIdFromToken = tenantClaim;
|
|
1515
|
+
}
|
|
1516
|
+
const issClaim = claims.iss;
|
|
1517
|
+
if (typeof issClaim === "string" && issClaim.length > 0) {
|
|
1518
|
+
issuerFromToken = issClaim;
|
|
1519
|
+
}
|
|
1520
|
+
}
|
|
1521
|
+
return {
|
|
1522
|
+
accessToken,
|
|
1523
|
+
baseUrl: parsedUrl.baseUrl,
|
|
1524
|
+
organizationName: parsedUrl.organizationName,
|
|
1525
|
+
organizationId: organizationIdFromToken ?? parsedUrl.organizationName,
|
|
1526
|
+
tenantName: parsedUrl.tenantName,
|
|
1527
|
+
tenantId: tenantIdFromToken,
|
|
1528
|
+
issuer: issuerFromToken
|
|
1529
|
+
};
|
|
1530
|
+
} catch {
|
|
1531
|
+
return;
|
|
1532
|
+
} finally {
|
|
1533
|
+
await catchError(() => withTimeout(proxy.CloseAsync(), CLOSE_TIMEOUT_MS));
|
|
1534
|
+
}
|
|
1535
|
+
};
|
|
1536
|
+
|
|
1537
|
+
// ../auth/src/tokenRefresh.ts
|
|
1538
|
+
var TOKEN_REFRESH_REAUTHENTICATE_MESSAGE = "Token refresh failed. Run 'uip login' to re-authenticate.";
|
|
1539
|
+
|
|
1540
|
+
class TokenRefreshOAuthError extends Error {
|
|
1541
|
+
__brand = "TokenRefreshOAuthError";
|
|
1542
|
+
constructor() {
|
|
1543
|
+
super(TOKEN_REFRESH_REAUTHENTICATE_MESSAGE);
|
|
1544
|
+
this.name = "TokenRefreshOAuthError";
|
|
1545
|
+
}
|
|
1546
|
+
}
|
|
1547
|
+
function isTokenRefreshOAuthFailure(error) {
|
|
1548
|
+
return error instanceof TokenRefreshOAuthError;
|
|
1549
|
+
}
|
|
1550
|
+
var refreshAccessToken = async ({
|
|
1551
|
+
refreshToken,
|
|
1552
|
+
tokenEndpoint,
|
|
1553
|
+
clientId,
|
|
1554
|
+
expectedAuthority
|
|
1555
|
+
}) => {
|
|
1556
|
+
const tokenParams = new URLSearchParams({
|
|
1557
|
+
grant_type: "refresh_token",
|
|
1558
|
+
refresh_token: refreshToken,
|
|
1559
|
+
client_id: clientId
|
|
1560
|
+
});
|
|
1561
|
+
const tokenResponse = await fetch(tokenEndpoint, {
|
|
1562
|
+
method: "POST",
|
|
1563
|
+
headers: {
|
|
1564
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
1565
|
+
},
|
|
1566
|
+
body: tokenParams
|
|
1567
|
+
});
|
|
1568
|
+
const tokenData = await tokenResponse.json();
|
|
1569
|
+
if (!tokenResponse.ok) {
|
|
1570
|
+
throw new TokenRefreshOAuthError;
|
|
1571
|
+
}
|
|
1572
|
+
const newAccessToken = tokenData.access_token;
|
|
1573
|
+
const newRefreshToken = tokenData.refresh_token;
|
|
1574
|
+
if (typeof newAccessToken !== "string" || typeof newRefreshToken !== "string") {
|
|
1575
|
+
throw new Error("Token refresh response is missing access_token or refresh_token");
|
|
1576
|
+
}
|
|
1577
|
+
if (expectedAuthority) {
|
|
1578
|
+
assertIssuerMatchesAuthority(newAccessToken, expectedAuthority);
|
|
1579
|
+
}
|
|
1580
|
+
return { accessToken: newAccessToken, refreshToken: newRefreshToken };
|
|
1581
|
+
};
|
|
1582
|
+
|
|
1583
|
+
// ../auth/src/types.ts
|
|
1584
|
+
var AUTH_FLOW_ENV_VAR = "UIPATH_AUTH_FLOW";
|
|
1585
|
+
|
|
1586
|
+
// ../auth/src/utils/envFile.ts
|
|
1587
|
+
init_src();
|
|
1588
|
+
init_constants();
|
|
1589
|
+
var DEFAULT_ENV_FILENAME = `${UIPATH_HOME_DIR}/${AUTH_FILENAME}`;
|
|
1590
|
+
var KNOWN_ERROR_CODES = new Set([
|
|
1591
|
+
"EISDIR",
|
|
1592
|
+
"EACCES",
|
|
1593
|
+
"EPERM",
|
|
1594
|
+
"ELOOP",
|
|
1595
|
+
"ENOTDIR",
|
|
1596
|
+
"EUNKNOWN"
|
|
1597
|
+
]);
|
|
1598
|
+
var errorCode = (err) => {
|
|
1599
|
+
if (err !== null && typeof err === "object" && "code" in err && typeof err.code === "string") {
|
|
1600
|
+
const raw = err.code;
|
|
1601
|
+
return KNOWN_ERROR_CODES.has(raw) ? raw : "EUNKNOWN";
|
|
1602
|
+
}
|
|
1603
|
+
return "EUNKNOWN";
|
|
1604
|
+
};
|
|
1605
|
+
var probeAsync = async (fs7, candidate) => {
|
|
1606
|
+
try {
|
|
1607
|
+
const stats = await fs7.stat(candidate);
|
|
1608
|
+
if (stats === null) {
|
|
1609
|
+
return { exists: false };
|
|
1610
|
+
}
|
|
1611
|
+
if (!stats.isFile()) {
|
|
1612
|
+
return {
|
|
1613
|
+
exists: false,
|
|
1614
|
+
unusable: {
|
|
1615
|
+
reason: "not-a-file",
|
|
1616
|
+
code: "EISDIR",
|
|
1617
|
+
message: `Path is not a regular file: ${candidate}`
|
|
1618
|
+
}
|
|
1619
|
+
};
|
|
1620
|
+
}
|
|
1621
|
+
return { exists: true };
|
|
1622
|
+
} catch (err) {
|
|
1623
|
+
return {
|
|
1624
|
+
exists: false,
|
|
1625
|
+
unusable: {
|
|
1626
|
+
reason: "unreadable",
|
|
1627
|
+
code: errorCode(err),
|
|
1628
|
+
message: err instanceof Error ? err.message : String(err)
|
|
1629
|
+
}
|
|
1630
|
+
};
|
|
1631
|
+
}
|
|
1632
|
+
};
|
|
1633
|
+
var resolveEnvFileLocationAsync = async (envFilePath = DEFAULT_ENV_FILENAME, opts) => {
|
|
1634
|
+
const fs7 = getFileSystem();
|
|
1635
|
+
if (fs7.path.isAbsolute(envFilePath)) {
|
|
1636
|
+
const probe2 = await probeAsync(fs7, envFilePath);
|
|
1637
|
+
return probe2.exists ? { exists: true, absolutePath: envFilePath, source: "absolute" } : {
|
|
1638
|
+
exists: false,
|
|
1639
|
+
absolutePath: envFilePath,
|
|
1640
|
+
source: "absolute",
|
|
1641
|
+
...probe2.unusable ? { unusable: probe2.unusable } : {}
|
|
1642
|
+
};
|
|
1643
|
+
}
|
|
1644
|
+
const cwd = opts?.cwd ?? fs7.env.cwd();
|
|
1645
|
+
let searchDir = cwd;
|
|
1646
|
+
while (true) {
|
|
1647
|
+
const candidate = fs7.path.join(searchDir, envFilePath);
|
|
1648
|
+
const probe2 = await probeAsync(fs7, candidate);
|
|
1649
|
+
if (probe2.exists) {
|
|
1650
|
+
return {
|
|
1651
|
+
exists: true,
|
|
1652
|
+
absolutePath: candidate,
|
|
1653
|
+
source: searchDir === cwd ? "cwd" : "ancestor"
|
|
1654
|
+
};
|
|
1655
|
+
}
|
|
1656
|
+
const parentDir = fs7.path.dirname(searchDir);
|
|
1657
|
+
if (parentDir === searchDir) {
|
|
1658
|
+
break;
|
|
1659
|
+
}
|
|
1660
|
+
searchDir = parentDir;
|
|
1661
|
+
}
|
|
1662
|
+
const homePath = fs7.path.join(fs7.env.homedir(), envFilePath);
|
|
1663
|
+
const probe = await probeAsync(fs7, homePath);
|
|
1664
|
+
if (probe.exists) {
|
|
1665
|
+
return { exists: true, absolutePath: homePath, source: "home" };
|
|
1666
|
+
}
|
|
1667
|
+
return {
|
|
1668
|
+
exists: false,
|
|
1669
|
+
absolutePath: homePath,
|
|
1670
|
+
source: "default",
|
|
1671
|
+
...probe.unusable ? { unusable: probe.unusable } : {}
|
|
1672
|
+
};
|
|
1673
|
+
};
|
|
1674
|
+
var resolveEnvFilePathAsync = async (envFilePath = DEFAULT_ENV_FILENAME, opts) => {
|
|
1675
|
+
const location = await resolveEnvFileLocationAsync(envFilePath, opts);
|
|
1676
|
+
if (location.exists) {
|
|
1677
|
+
return { absolutePath: location.absolutePath };
|
|
1678
|
+
}
|
|
1679
|
+
return {
|
|
1680
|
+
absolutePath: undefined,
|
|
1681
|
+
errorMessage: location.source === "absolute" ? `Environment file not found: ${envFilePath}` : `Unable to locate environment file: ${envFilePath}. Run 'uip login' to authenticate.`
|
|
1682
|
+
};
|
|
1683
|
+
};
|
|
1684
|
+
var loadEnvFileAsync = async ({ envPath }) => {
|
|
1685
|
+
const fs7 = getFileSystem();
|
|
1686
|
+
const absolutePath = fs7.path.isAbsolute(envPath) ? envPath : fs7.path.join(fs7.env.cwd(), envPath);
|
|
1687
|
+
if (!await fs7.exists(absolutePath)) {
|
|
1688
|
+
throw new Error(`Environment file not found: ${envPath}`);
|
|
1689
|
+
}
|
|
1690
|
+
const content = await fs7.readFile(absolutePath, "utf-8");
|
|
1691
|
+
if (content === null) {
|
|
1692
|
+
throw new Error(`Environment file not found: ${envPath}`);
|
|
1693
|
+
}
|
|
1694
|
+
const env = {};
|
|
1695
|
+
for (const line of content.split(`
|
|
1696
|
+
`)) {
|
|
1697
|
+
const trimmed = line.trim();
|
|
1698
|
+
if (!trimmed || trimmed.startsWith("#")) {
|
|
1699
|
+
continue;
|
|
1700
|
+
}
|
|
1701
|
+
const equalIndex = trimmed.indexOf("=");
|
|
1702
|
+
if (equalIndex === -1) {
|
|
1703
|
+
continue;
|
|
1704
|
+
}
|
|
1705
|
+
const key = trimmed.slice(0, equalIndex).trim();
|
|
1706
|
+
let value = trimmed.slice(equalIndex + 1).trim();
|
|
1707
|
+
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
1708
|
+
value = value.slice(1, -1);
|
|
1709
|
+
}
|
|
1710
|
+
env[key] = value;
|
|
1711
|
+
}
|
|
1712
|
+
return env;
|
|
1713
|
+
};
|
|
1714
|
+
var saveEnvFileAsync = async ({
|
|
1715
|
+
envPath,
|
|
1716
|
+
data,
|
|
1717
|
+
merge = true
|
|
1718
|
+
}) => {
|
|
1719
|
+
const fs7 = getFileSystem();
|
|
1720
|
+
const absolutePath = fs7.path.isAbsolute(envPath) ? envPath : fs7.path.join(fs7.env.homedir(), envPath);
|
|
1721
|
+
let existingData = {};
|
|
1722
|
+
if (merge && await fs7.exists(absolutePath)) {
|
|
1723
|
+
try {
|
|
1724
|
+
existingData = await loadEnvFileAsync({ envPath: absolutePath });
|
|
1725
|
+
} catch {}
|
|
1726
|
+
}
|
|
1727
|
+
const finalData = { ...existingData, ...data };
|
|
1728
|
+
const lines = [];
|
|
1729
|
+
for (const [key, value] of Object.entries(finalData)) {
|
|
1730
|
+
if (value === undefined) {
|
|
1731
|
+
continue;
|
|
1732
|
+
}
|
|
1733
|
+
const needsQuotes = value.includes(" ") || value.includes("#");
|
|
1734
|
+
const finalValue = needsQuotes ? `"${value}"` : value;
|
|
1735
|
+
lines.push(`${key}=${finalValue}`);
|
|
1736
|
+
}
|
|
1737
|
+
const content = `${lines.join(`
|
|
1738
|
+
`)}
|
|
1739
|
+
`;
|
|
1740
|
+
const dir = fs7.path.dirname(absolutePath);
|
|
1741
|
+
await fs7.mkdir(dir);
|
|
1742
|
+
const tempPath = `${absolutePath}.tmp`;
|
|
1743
|
+
await fs7.writeFile(tempPath, content);
|
|
1744
|
+
await fs7.rename(tempPath, absolutePath);
|
|
1745
|
+
};
|
|
1746
|
+
|
|
1747
|
+
// ../auth/src/loginStatus.ts
|
|
1748
|
+
var getLoginStatusAsync = async (options = {}) => {
|
|
1749
|
+
return getLoginStatusWithDeps(options);
|
|
1750
|
+
};
|
|
1751
|
+
var getLoginStatusWithDeps = async (options = {}, deps = {}) => {
|
|
1752
|
+
const {
|
|
1753
|
+
resolveEnvFilePath = resolveEnvFilePathAsync,
|
|
1754
|
+
loadEnvFile = loadEnvFileAsync,
|
|
1755
|
+
saveEnvFile = saveEnvFileAsync,
|
|
1756
|
+
getFs = getFileSystem,
|
|
1757
|
+
refreshToken: refreshTokenFn = refreshAccessToken,
|
|
1758
|
+
resolveConfig = resolveConfigAsync,
|
|
1759
|
+
robotFallback = tryRobotClientFallback,
|
|
1760
|
+
loadBreaker = loadRefreshBreaker,
|
|
1761
|
+
saveBreaker = saveRefreshBreaker,
|
|
1762
|
+
clearBreaker = clearRefreshBreaker
|
|
1763
|
+
} = deps;
|
|
1764
|
+
if (isRobotAuthEnforced()) {
|
|
1765
|
+
return resolveRobotEnforcedStatus(robotFallback);
|
|
1766
|
+
}
|
|
1767
|
+
if (isEnvAuthEnabled()) {
|
|
1768
|
+
return readAuthFromEnv();
|
|
1769
|
+
}
|
|
1770
|
+
const activeProfile = getActiveAuthProfile();
|
|
1771
|
+
const activeProfileFilePath = getActiveAuthProfileFilePath();
|
|
1772
|
+
const usingActiveProfile = activeProfile !== undefined && (options.envFilePath === undefined || options.envFilePath === activeProfileFilePath);
|
|
1773
|
+
const envFilePath = options.envFilePath ?? activeProfileFilePath ?? DEFAULT_ENV_FILENAME;
|
|
1774
|
+
const { ensureTokenValidityMinutes } = options;
|
|
1775
|
+
const { absolutePath } = await resolveEnvFilePath(envFilePath);
|
|
1776
|
+
if (absolutePath === undefined) {
|
|
1777
|
+
if (usingActiveProfile) {
|
|
1778
|
+
return {
|
|
1779
|
+
loginStatus: "Not logged in",
|
|
1780
|
+
hint: `No credentials found for profile "${activeProfile}". Run 'uip login --profile ${activeProfile}' to authenticate this profile.`
|
|
1781
|
+
};
|
|
1782
|
+
}
|
|
1783
|
+
return resolveBorrowedRobotStatus(robotFallback);
|
|
1784
|
+
}
|
|
1785
|
+
const loaded = await loadFileCredentials(loadEnvFile, absolutePath);
|
|
1786
|
+
if ("status" in loaded) {
|
|
1787
|
+
return loaded.status;
|
|
1788
|
+
}
|
|
1789
|
+
const { credentials } = loaded;
|
|
1790
|
+
const globalHint = () => usingActiveProfile ? Promise.resolve(undefined) : getGlobalCredsHint(getFs, loadEnvFile, absolutePath, envFilePath);
|
|
1791
|
+
const expiration = getTokenExpiration(credentials.UIPATH_ACCESS_TOKEN);
|
|
1792
|
+
const outerThreshold = computeExpirationThreshold(ensureTokenValidityMinutes);
|
|
1793
|
+
let tokens = {
|
|
1794
|
+
accessToken: credentials.UIPATH_ACCESS_TOKEN,
|
|
1795
|
+
refreshToken: credentials.UIPATH_REFRESH_TOKEN,
|
|
1796
|
+
expiration,
|
|
1797
|
+
lockReleaseFailed: false
|
|
1798
|
+
};
|
|
1799
|
+
const refreshToken = credentials.UIPATH_REFRESH_TOKEN;
|
|
1800
|
+
if (expiration && expiration <= outerThreshold && refreshToken) {
|
|
1801
|
+
const refreshed = await attemptRefresh({
|
|
1802
|
+
absolutePath,
|
|
1803
|
+
credentials,
|
|
1804
|
+
accessToken: credentials.UIPATH_ACCESS_TOKEN,
|
|
1805
|
+
refreshToken,
|
|
1806
|
+
expiration,
|
|
1807
|
+
ensureTokenValidityMinutes,
|
|
1808
|
+
getFs,
|
|
1809
|
+
loadEnvFile,
|
|
1810
|
+
saveEnvFile,
|
|
1811
|
+
refreshFn: refreshTokenFn,
|
|
1812
|
+
resolveConfig,
|
|
1813
|
+
loadBreaker,
|
|
1814
|
+
saveBreaker,
|
|
1815
|
+
clearBreaker,
|
|
1816
|
+
globalHint
|
|
1817
|
+
});
|
|
1818
|
+
if (refreshed.kind === "terminal") {
|
|
1819
|
+
return refreshed.status;
|
|
1820
|
+
}
|
|
1821
|
+
tokens = refreshed.tokens;
|
|
1822
|
+
}
|
|
1823
|
+
return buildFileStatus(tokens, credentials, globalHint);
|
|
1824
|
+
};
|
|
1825
|
+
async function resolveRobotEnforcedStatus(robotFallback) {
|
|
1826
|
+
if (isEnvAuthEnabled()) {
|
|
1827
|
+
throw new EnvAuthConfigError(`${ENV_AUTH_ENABLE_VAR}=true and ${ENFORCE_ROBOT_AUTH_VAR}=true ` + `are mutually exclusive. Unset one of them and re-run.`);
|
|
1828
|
+
}
|
|
1829
|
+
const robotCreds = await robotFallback({ force: true });
|
|
1830
|
+
if (!robotCreds) {
|
|
1831
|
+
return {
|
|
1832
|
+
loginStatus: "Not logged in",
|
|
1833
|
+
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.`
|
|
1834
|
+
};
|
|
1835
|
+
}
|
|
1836
|
+
return buildRobotStatus(robotCreds);
|
|
1837
|
+
}
|
|
1838
|
+
async function resolveBorrowedRobotStatus(robotFallback) {
|
|
1839
|
+
const robotCreds = await robotFallback();
|
|
1840
|
+
return robotCreds ? buildRobotStatus(robotCreds) : { loginStatus: "Not logged in" };
|
|
1841
|
+
}
|
|
1842
|
+
async function loadFileCredentials(loadEnvFile, absolutePath) {
|
|
1843
|
+
let credentials;
|
|
1844
|
+
try {
|
|
1845
|
+
credentials = await loadEnvFile({ envPath: absolutePath });
|
|
1846
|
+
} catch (error) {
|
|
1847
|
+
if (isFileNotFoundError(error)) {
|
|
1848
|
+
return { status: { loginStatus: "Not logged in" } };
|
|
1849
|
+
}
|
|
1850
|
+
throw error;
|
|
1851
|
+
}
|
|
1852
|
+
if (!credentials.UIPATH_ACCESS_TOKEN) {
|
|
1853
|
+
return { status: { loginStatus: "Not logged in" } };
|
|
1854
|
+
}
|
|
1855
|
+
return { credentials };
|
|
1856
|
+
}
|
|
1857
|
+
async function getGlobalCredsHint(getFs, loadEnvFile, absolutePath, envFilePath) {
|
|
1858
|
+
const fs7 = getFs();
|
|
1859
|
+
const globalPath = fs7.path.join(fs7.env.homedir(), envFilePath);
|
|
1860
|
+
if (absolutePath === globalPath)
|
|
1861
|
+
return;
|
|
1862
|
+
if (!await fs7.exists(globalPath))
|
|
1863
|
+
return;
|
|
1864
|
+
try {
|
|
1865
|
+
const globalCreds = await loadEnvFile({ envPath: globalPath });
|
|
1866
|
+
if (!globalCreds.UIPATH_ACCESS_TOKEN)
|
|
1867
|
+
return;
|
|
1868
|
+
const globalExp = getTokenExpiration(globalCreds.UIPATH_ACCESS_TOKEN);
|
|
1869
|
+
if (globalExp && globalExp <= new Date)
|
|
1870
|
+
return;
|
|
1871
|
+
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.`;
|
|
1872
|
+
} catch {
|
|
1873
|
+
return;
|
|
1874
|
+
}
|
|
1875
|
+
}
|
|
1876
|
+
function computeExpirationThreshold(ensureTokenValidityMinutes) {
|
|
1877
|
+
return new Date(Date.now() + (ensureTokenValidityMinutes ?? 0) * 60 * 1000);
|
|
1878
|
+
}
|
|
1879
|
+
async function attemptRefresh(ctx) {
|
|
1880
|
+
const shortCircuit = await circuitBreakerShortCircuit(ctx);
|
|
1881
|
+
if (shortCircuit) {
|
|
1882
|
+
return { kind: "terminal", status: shortCircuit };
|
|
1883
|
+
}
|
|
1884
|
+
let release;
|
|
1885
|
+
try {
|
|
1886
|
+
release = await ctx.getFs().acquireLock(ctx.absolutePath);
|
|
1887
|
+
} catch (error) {
|
|
1888
|
+
return {
|
|
1889
|
+
kind: "terminal",
|
|
1890
|
+
status: await lockAcquireFailureStatus(ctx, error)
|
|
1891
|
+
};
|
|
1892
|
+
}
|
|
1893
|
+
let lockedFailure;
|
|
1894
|
+
let lockReleaseFailed = false;
|
|
1895
|
+
let success;
|
|
1896
|
+
try {
|
|
1897
|
+
const outcome = await runRefreshLocked({
|
|
1898
|
+
absolutePath: ctx.absolutePath,
|
|
1899
|
+
refreshToken: ctx.refreshToken,
|
|
1900
|
+
customAuthority: ctx.credentials.UIPATH_URL,
|
|
1901
|
+
ensureTokenValidityMinutes: ctx.ensureTokenValidityMinutes,
|
|
1902
|
+
loadEnvFile: ctx.loadEnvFile,
|
|
1903
|
+
saveEnvFile: ctx.saveEnvFile,
|
|
1904
|
+
refreshFn: ctx.refreshFn,
|
|
1905
|
+
resolveConfig: ctx.resolveConfig,
|
|
1906
|
+
loadBreaker: ctx.loadBreaker,
|
|
1907
|
+
saveBreaker: ctx.saveBreaker,
|
|
1908
|
+
clearBreaker: ctx.clearBreaker
|
|
1909
|
+
});
|
|
1910
|
+
if (outcome.kind === "fail") {
|
|
1911
|
+
lockedFailure = outcome.status;
|
|
1912
|
+
} else {
|
|
1913
|
+
success = outcome;
|
|
1914
|
+
}
|
|
1915
|
+
} finally {
|
|
1916
|
+
try {
|
|
1917
|
+
await release();
|
|
1918
|
+
} catch {
|
|
1919
|
+
lockReleaseFailed = true;
|
|
1920
|
+
}
|
|
1921
|
+
}
|
|
1922
|
+
if (lockedFailure) {
|
|
1923
|
+
const globalHint = await ctx.globalHint();
|
|
1924
|
+
const base = globalHint ? { ...lockedFailure, loginStatus: "Expired", hint: globalHint } : lockedFailure;
|
|
1925
|
+
return {
|
|
1926
|
+
kind: "terminal",
|
|
1927
|
+
status: lockReleaseFailed ? { ...base, lockReleaseFailed: true } : base
|
|
1928
|
+
};
|
|
1929
|
+
}
|
|
1930
|
+
return {
|
|
1931
|
+
kind: "refreshed",
|
|
1932
|
+
tokens: {
|
|
1933
|
+
accessToken: success?.accessToken,
|
|
1934
|
+
refreshToken: success?.refreshToken,
|
|
1935
|
+
expiration: success?.expiration,
|
|
1936
|
+
tokenRefresh: success?.tokenRefresh,
|
|
1937
|
+
persistenceWarning: success?.persistenceWarning,
|
|
1938
|
+
lockReleaseFailed
|
|
1939
|
+
}
|
|
1940
|
+
};
|
|
1941
|
+
}
|
|
1942
|
+
async function buildFileStatus(tokens, credentials, globalHint) {
|
|
1943
|
+
const result = {
|
|
1944
|
+
loginStatus: tokens.expiration && tokens.expiration <= new Date ? "Expired" : "Logged in",
|
|
1945
|
+
accessToken: tokens.accessToken,
|
|
1946
|
+
refreshToken: tokens.refreshToken,
|
|
1947
|
+
baseUrl: credentials.UIPATH_URL,
|
|
1948
|
+
organizationName: credentials.UIPATH_ORGANIZATION_NAME,
|
|
1949
|
+
organizationId: credentials.UIPATH_ORGANIZATION_ID,
|
|
1950
|
+
tenantName: credentials.UIPATH_TENANT_NAME,
|
|
1951
|
+
tenantId: credentials.UIPATH_TENANT_ID,
|
|
1952
|
+
expiration: tokens.expiration,
|
|
1953
|
+
source: "saved-login" /* SavedLogin */,
|
|
1954
|
+
...identityFields(tokens.accessToken, credentials),
|
|
1955
|
+
...tokens.persistenceWarning ? { hint: tokens.persistenceWarning, persistenceFailed: true } : {},
|
|
1956
|
+
...tokens.lockReleaseFailed ? { lockReleaseFailed: true } : {},
|
|
1957
|
+
...tokens.tokenRefresh ? { tokenRefresh: tokens.tokenRefresh } : {}
|
|
1958
|
+
};
|
|
1959
|
+
if (result.loginStatus === "Expired") {
|
|
1960
|
+
const hint = await globalHint();
|
|
1961
|
+
if (hint) {
|
|
1962
|
+
result.hint = hint;
|
|
1963
|
+
}
|
|
1964
|
+
}
|
|
1965
|
+
return result;
|
|
1966
|
+
}
|
|
1967
|
+
function identityFields(accessToken, credentials) {
|
|
1968
|
+
const identity = resolveSessionIdentity(accessToken, parseAuthFlow(credentials[AUTH_FLOW_ENV_VAR]));
|
|
1969
|
+
return identity ? { identity } : {};
|
|
1970
|
+
}
|
|
1971
|
+
function buildRobotStatus(robotCreds) {
|
|
1972
|
+
const identity = resolveSessionIdentity(robotCreds.accessToken);
|
|
1973
|
+
return {
|
|
1974
|
+
loginStatus: "Logged in",
|
|
1975
|
+
accessToken: robotCreds.accessToken,
|
|
1976
|
+
baseUrl: robotCreds.baseUrl,
|
|
1977
|
+
organizationName: robotCreds.organizationName,
|
|
1978
|
+
organizationId: robotCreds.organizationId,
|
|
1979
|
+
tenantName: robotCreds.tenantName,
|
|
1980
|
+
tenantId: robotCreds.tenantId,
|
|
1981
|
+
issuer: robotCreds.issuer,
|
|
1982
|
+
expiration: getTokenExpiration(robotCreds.accessToken),
|
|
1983
|
+
source: "robot" /* Robot */,
|
|
1984
|
+
...identity ? { identity } : {}
|
|
1985
|
+
};
|
|
1986
|
+
}
|
|
1987
|
+
var isFileNotFoundError = (error) => {
|
|
1988
|
+
if (!(error instanceof Object))
|
|
1989
|
+
return false;
|
|
1990
|
+
return error.code === "ENOENT";
|
|
1991
|
+
};
|
|
1992
|
+
async function circuitBreakerShortCircuit(ctx) {
|
|
1993
|
+
const {
|
|
1994
|
+
absolutePath,
|
|
1995
|
+
refreshToken,
|
|
1996
|
+
accessToken,
|
|
1997
|
+
credentials,
|
|
1998
|
+
expiration,
|
|
1999
|
+
loadBreaker,
|
|
2000
|
+
saveBreaker,
|
|
2001
|
+
clearBreaker
|
|
2002
|
+
} = ctx;
|
|
2003
|
+
const fingerprint = await refreshTokenFingerprint(refreshToken);
|
|
2004
|
+
const breaker = await loadBreaker(absolutePath).catch(() => ({}));
|
|
2005
|
+
if (breaker.deadTokenFp && breaker.deadTokenFp !== fingerprint) {
|
|
2006
|
+
await clearBreaker(absolutePath);
|
|
2007
|
+
breaker.deadTokenFp = undefined;
|
|
2008
|
+
}
|
|
2009
|
+
const nowMs = Date.now();
|
|
2010
|
+
const tokenIsDead = breaker.deadTokenFp === fingerprint;
|
|
2011
|
+
const inBackoff = breaker.backoffUntilMs !== undefined && nowMs < breaker.backoffUntilMs;
|
|
2012
|
+
if (!tokenIsDead && !inBackoff)
|
|
2013
|
+
return;
|
|
2014
|
+
const globalHint = await ctx.globalHint();
|
|
2015
|
+
const suppressed = !shouldSurface(breaker, nowMs);
|
|
2016
|
+
if (!suppressed) {
|
|
2017
|
+
await saveBreaker(absolutePath, {
|
|
2018
|
+
...breaker,
|
|
2019
|
+
lastSurfacedAtMs: nowMs
|
|
2020
|
+
});
|
|
2021
|
+
}
|
|
2022
|
+
const deadHint = "Run 'uip login' to re-authenticate — the stored refresh token is invalid or expired. In a non-interactive context, authenticate with: uip login --client-id <id> --client-secret <secret> -t <tenant>.";
|
|
2023
|
+
const backoffHint = "Token refresh is temporarily backed off after a recent network error and will retry automatically once the backoff window elapses.";
|
|
2024
|
+
return {
|
|
2025
|
+
loginStatus: globalHint ? "Expired" : "Refresh Failed",
|
|
2026
|
+
...globalHint ? {
|
|
2027
|
+
accessToken,
|
|
2028
|
+
refreshToken,
|
|
2029
|
+
baseUrl: credentials.UIPATH_URL,
|
|
2030
|
+
organizationName: credentials.UIPATH_ORGANIZATION_NAME,
|
|
2031
|
+
organizationId: credentials.UIPATH_ORGANIZATION_ID,
|
|
2032
|
+
tenantName: credentials.UIPATH_TENANT_NAME,
|
|
2033
|
+
tenantId: credentials.UIPATH_TENANT_ID,
|
|
2034
|
+
expiration,
|
|
2035
|
+
source: "saved-login" /* SavedLogin */,
|
|
2036
|
+
...identityFields(accessToken, credentials)
|
|
2037
|
+
} : {},
|
|
2038
|
+
hint: globalHint ?? (tokenIsDead ? deadHint : backoffHint),
|
|
2039
|
+
refreshCircuitOpen: true,
|
|
2040
|
+
refreshTelemetrySuppressed: suppressed,
|
|
2041
|
+
tokenRefresh: { attempted: false, success: false }
|
|
2042
|
+
};
|
|
2043
|
+
}
|
|
2044
|
+
async function lockAcquireFailureStatus(ctx, error) {
|
|
2045
|
+
const msg = errorMessage(error);
|
|
2046
|
+
const globalHint = await ctx.globalHint();
|
|
2047
|
+
if (globalHint) {
|
|
2048
|
+
return {
|
|
2049
|
+
loginStatus: "Expired",
|
|
2050
|
+
accessToken: ctx.accessToken,
|
|
2051
|
+
refreshToken: ctx.refreshToken,
|
|
2052
|
+
baseUrl: ctx.credentials.UIPATH_URL,
|
|
2053
|
+
organizationName: ctx.credentials.UIPATH_ORGANIZATION_NAME,
|
|
2054
|
+
organizationId: ctx.credentials.UIPATH_ORGANIZATION_ID,
|
|
2055
|
+
tenantName: ctx.credentials.UIPATH_TENANT_NAME,
|
|
2056
|
+
tenantId: ctx.credentials.UIPATH_TENANT_ID,
|
|
2057
|
+
expiration: ctx.expiration,
|
|
2058
|
+
source: "saved-login" /* SavedLogin */,
|
|
2059
|
+
...identityFields(ctx.accessToken, ctx.credentials),
|
|
2060
|
+
hint: globalHint,
|
|
2061
|
+
tokenRefresh: {
|
|
2062
|
+
attempted: false,
|
|
2063
|
+
success: false,
|
|
2064
|
+
errorMessage: `lock acquisition failed: ${msg}`
|
|
2065
|
+
}
|
|
2066
|
+
};
|
|
2067
|
+
}
|
|
2068
|
+
return {
|
|
2069
|
+
loginStatus: "Refresh Failed",
|
|
2070
|
+
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.",
|
|
2071
|
+
tokenRefresh: {
|
|
2072
|
+
attempted: false,
|
|
2073
|
+
success: false,
|
|
2074
|
+
errorMessage: `lock acquisition failed: ${msg}`
|
|
2075
|
+
}
|
|
2076
|
+
};
|
|
2077
|
+
}
|
|
2078
|
+
async function runRefreshLocked(inputs) {
|
|
2079
|
+
const {
|
|
2080
|
+
absolutePath,
|
|
2081
|
+
refreshToken: callerRefreshToken,
|
|
2082
|
+
customAuthority,
|
|
2083
|
+
ensureTokenValidityMinutes,
|
|
2084
|
+
loadEnvFile,
|
|
2085
|
+
saveEnvFile,
|
|
2086
|
+
refreshFn,
|
|
2087
|
+
resolveConfig,
|
|
2088
|
+
loadBreaker,
|
|
2089
|
+
saveBreaker,
|
|
2090
|
+
clearBreaker
|
|
2091
|
+
} = inputs;
|
|
2092
|
+
const expirationThreshold = computeExpirationThreshold(ensureTokenValidityMinutes);
|
|
2093
|
+
let fresh;
|
|
2094
|
+
try {
|
|
2095
|
+
fresh = await loadEnvFile({ envPath: absolutePath });
|
|
2096
|
+
} catch (error) {
|
|
2097
|
+
return {
|
|
2098
|
+
kind: "fail",
|
|
2099
|
+
status: {
|
|
2100
|
+
loginStatus: "Refresh Failed",
|
|
2101
|
+
hint: "Could not read the auth file while refreshing. Retry, or run 'uip login' to re-authenticate.",
|
|
2102
|
+
tokenRefresh: {
|
|
2103
|
+
attempted: false,
|
|
2104
|
+
success: false,
|
|
2105
|
+
errorMessage: `auth file read failed: ${errorMessage(error)}`
|
|
2106
|
+
}
|
|
2107
|
+
}
|
|
2108
|
+
};
|
|
2109
|
+
}
|
|
2110
|
+
const freshAccess = fresh.UIPATH_ACCESS_TOKEN;
|
|
2111
|
+
const freshExp = freshAccess ? getTokenExpiration(freshAccess) : undefined;
|
|
2112
|
+
if (freshAccess && freshExp && freshExp > expirationThreshold) {
|
|
2113
|
+
await clearBreaker(absolutePath);
|
|
2114
|
+
return {
|
|
2115
|
+
kind: "ok",
|
|
2116
|
+
accessToken: freshAccess,
|
|
2117
|
+
refreshToken: fresh.UIPATH_REFRESH_TOKEN ?? callerRefreshToken,
|
|
2118
|
+
expiration: freshExp,
|
|
2119
|
+
tokenRefresh: { attempted: false, success: true }
|
|
2120
|
+
};
|
|
2121
|
+
}
|
|
2122
|
+
const tokenForIdP = fresh.UIPATH_REFRESH_TOKEN ?? callerRefreshToken;
|
|
2123
|
+
let refreshedAccess;
|
|
2124
|
+
let refreshedRefresh;
|
|
2125
|
+
try {
|
|
2126
|
+
const config = await resolveConfig({ customAuthority });
|
|
2127
|
+
const refreshed = await refreshFn({
|
|
2128
|
+
refreshToken: tokenForIdP,
|
|
2129
|
+
tokenEndpoint: config.tokenEndpoint,
|
|
2130
|
+
clientId: config.clientId,
|
|
2131
|
+
expectedAuthority: customAuthority
|
|
2132
|
+
});
|
|
2133
|
+
refreshedAccess = refreshed.accessToken;
|
|
2134
|
+
refreshedRefresh = refreshed.refreshToken;
|
|
2135
|
+
} catch (error) {
|
|
2136
|
+
const isOAuthFailure = isTokenRefreshOAuthFailure(error);
|
|
2137
|
+
const hint = isOAuthFailure ? "Run 'uip login' to re-authenticate — the stored refresh token is invalid or expired. In a non-interactive context, authenticate with: uip login --client-id <id> --client-secret <secret> -t <tenant>." : "Token refresh failed. Check your network connection, then retry or run 'uip login' to re-authenticate.";
|
|
2138
|
+
const message = isOAuthFailure ? normalizeTokenRefreshFailure() : normalizeTokenRefreshUnavailableFailure();
|
|
2139
|
+
const fp = await refreshTokenFingerprint(tokenForIdP);
|
|
2140
|
+
if (isOAuthFailure) {
|
|
2141
|
+
await saveBreaker(absolutePath, { deadTokenFp: fp });
|
|
2142
|
+
} else {
|
|
2143
|
+
const prior = await loadBreaker(absolutePath).catch(() => ({}));
|
|
2144
|
+
const attempts = (prior.attempts ?? 0) + 1;
|
|
2145
|
+
await saveBreaker(absolutePath, {
|
|
2146
|
+
...prior,
|
|
2147
|
+
deadTokenFp: undefined,
|
|
2148
|
+
attempts,
|
|
2149
|
+
backoffUntilMs: Date.now() + nextBackoffMs(attempts)
|
|
2150
|
+
});
|
|
2151
|
+
}
|
|
2152
|
+
return {
|
|
2153
|
+
kind: "fail",
|
|
2154
|
+
status: {
|
|
2155
|
+
loginStatus: "Refresh Failed",
|
|
2156
|
+
hint,
|
|
2157
|
+
tokenRefresh: {
|
|
2158
|
+
attempted: true,
|
|
2159
|
+
success: false,
|
|
2160
|
+
errorMessage: message
|
|
2161
|
+
}
|
|
2162
|
+
}
|
|
2163
|
+
};
|
|
2164
|
+
}
|
|
2165
|
+
const refreshedExp = getTokenExpiration(refreshedAccess);
|
|
2166
|
+
if (!refreshedExp || refreshedExp <= new Date) {
|
|
2167
|
+
return {
|
|
2168
|
+
kind: "fail",
|
|
2169
|
+
status: {
|
|
2170
|
+
loginStatus: "Refresh Failed",
|
|
2171
|
+
hint: "The identity server returned an unusable token. Run 'uip login' to re-authenticate.",
|
|
2172
|
+
tokenRefresh: {
|
|
2173
|
+
attempted: true,
|
|
2174
|
+
success: false,
|
|
2175
|
+
errorMessage: "refreshed token has no valid expiration claim"
|
|
2176
|
+
}
|
|
2177
|
+
}
|
|
2178
|
+
};
|
|
2179
|
+
}
|
|
2180
|
+
await clearBreaker(absolutePath);
|
|
2181
|
+
try {
|
|
2182
|
+
await saveEnvFile({
|
|
2183
|
+
envPath: absolutePath,
|
|
2184
|
+
data: {
|
|
2185
|
+
UIPATH_ACCESS_TOKEN: refreshedAccess,
|
|
2186
|
+
UIPATH_REFRESH_TOKEN: refreshedRefresh
|
|
2187
|
+
},
|
|
2188
|
+
merge: true
|
|
2189
|
+
});
|
|
2190
|
+
return {
|
|
2191
|
+
kind: "ok",
|
|
2192
|
+
accessToken: refreshedAccess,
|
|
2193
|
+
refreshToken: refreshedRefresh,
|
|
2194
|
+
expiration: refreshedExp,
|
|
2195
|
+
tokenRefresh: { attempted: true, success: true }
|
|
2196
|
+
};
|
|
2197
|
+
} catch (error) {
|
|
2198
|
+
const msg = errorMessage(error);
|
|
2199
|
+
return {
|
|
2200
|
+
kind: "ok",
|
|
2201
|
+
accessToken: refreshedAccess,
|
|
2202
|
+
refreshToken: refreshedRefresh,
|
|
2203
|
+
expiration: refreshedExp,
|
|
2204
|
+
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.`,
|
|
2205
|
+
tokenRefresh: {
|
|
2206
|
+
attempted: true,
|
|
2207
|
+
success: true,
|
|
2208
|
+
errorMessage: `persistence failed: ${msg}`
|
|
2209
|
+
}
|
|
2210
|
+
};
|
|
2211
|
+
}
|
|
2212
|
+
}
|
|
2213
|
+
function normalizeTokenRefreshFailure() {
|
|
2214
|
+
return "stored refresh token is invalid or expired";
|
|
2215
|
+
}
|
|
2216
|
+
function normalizeTokenRefreshUnavailableFailure() {
|
|
2217
|
+
return "token refresh failed before authentication completed";
|
|
2218
|
+
}
|
|
2219
|
+
function errorMessage(error) {
|
|
2220
|
+
return error instanceof Error ? error.message : String(error);
|
|
2221
|
+
}
|
|
2222
|
+
|
|
2223
|
+
// ../auth/src/authContext.ts
|
|
2224
|
+
var getAuthContext = async (options = {}) => {
|
|
2225
|
+
const status = await getLoginStatusAsync({
|
|
2226
|
+
ensureTokenValidityMinutes: options.ensureTokenValidityMinutes,
|
|
2227
|
+
envFilePath: options.envFilePath
|
|
2228
|
+
});
|
|
2229
|
+
if (status.loginStatus !== "Logged in" || !status.baseUrl || !status.accessToken) {
|
|
2230
|
+
throw new Error(status.hint ? `Not logged in. ${status.hint}` : "Not logged in. Run 'uip login' first.");
|
|
2231
|
+
}
|
|
2232
|
+
const tenantName = options.tenant ?? status.tenantName;
|
|
2233
|
+
if (options.requireOrganizationId && !status.organizationId) {
|
|
2234
|
+
throw new Error("Organization ID not available. Ensure you are logged in with an organization context.");
|
|
2235
|
+
}
|
|
2236
|
+
if (options.requireOrganizationName && !status.organizationName) {
|
|
2237
|
+
throw new Error("Organization name not available. Ensure you are logged in with an organization context.");
|
|
2238
|
+
}
|
|
2239
|
+
if (options.requireTenantId && !status.tenantId) {
|
|
2240
|
+
throw new Error("Tenant ID not available. Ensure UIPATH_TENANT_ID is set.");
|
|
2241
|
+
}
|
|
2242
|
+
if (options.requireTenantName && tenantName === undefined) {
|
|
2243
|
+
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.");
|
|
2244
|
+
}
|
|
2245
|
+
return {
|
|
2246
|
+
baseUrl: status.baseUrl,
|
|
2247
|
+
accessToken: status.accessToken,
|
|
2248
|
+
organizationId: status.organizationId,
|
|
2249
|
+
organizationName: status.organizationName,
|
|
2250
|
+
tenantId: status.tenantId,
|
|
2251
|
+
tenantName
|
|
2252
|
+
};
|
|
2253
|
+
};
|
|
2254
|
+
// ../auth/src/index.ts
|
|
2255
|
+
init_constants();
|
|
2256
|
+
|
|
2257
|
+
// ../auth/src/interactive.ts
|
|
2258
|
+
init_src();
|
|
2259
|
+
|
|
2260
|
+
// ../auth/src/selectTenant.ts
|
|
2261
|
+
var TENANT_SELECTION_REQUIRED_CODE = "TENANT_SELECTION_REQUIRED";
|
|
2262
|
+
var INVALID_TENANT_CODE = "INVALID_TENANT";
|
|
2263
|
+
var TENANT_SELECTION_CODES = new Set([
|
|
2264
|
+
TENANT_SELECTION_REQUIRED_CODE,
|
|
2265
|
+
INVALID_TENANT_CODE
|
|
2266
|
+
]);
|
|
2267
|
+
// ../auth/src/logout.ts
|
|
2268
|
+
init_src();
|
|
2269
|
+
// src/solution-auth.ts
|
|
2270
|
+
async function getSolutionAuthContext(options) {
|
|
2271
|
+
const ctx = await getAuthContext({
|
|
2272
|
+
tenant: options.tenant,
|
|
2273
|
+
ensureTokenValidityMinutes: options.loginValidity ?? 10,
|
|
2274
|
+
envFilePath: options.envFilePath,
|
|
2275
|
+
requireOrganizationId: true,
|
|
2276
|
+
requireTenantName: true
|
|
2277
|
+
});
|
|
2278
|
+
const organizationId = ctx.organizationId;
|
|
2279
|
+
const tenantName = ctx.tenantName;
|
|
2280
|
+
const basePath = `${ctx.baseUrl}/${organizationId}/${tenantName}/automationsolutions_`;
|
|
2281
|
+
return {
|
|
2282
|
+
accessToken: ctx.accessToken,
|
|
2283
|
+
basePath,
|
|
2284
|
+
organizationId,
|
|
2285
|
+
tenantName
|
|
2286
|
+
};
|
|
2287
|
+
}
|
|
2288
|
+
export {
|
|
2289
|
+
getSolutionAuthContext
|
|
2290
|
+
};
|
|
2291
|
+
|
|
2292
|
+
//# debugId=A8D037BD2594097C64756E2164756E21
|