@uipath/auth 1.197.0 → 1.198.0-preview.80

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.
@@ -6,5 +6,6 @@ export declare const AUTH_FILENAME = ".auth";
6
6
  export declare const DEFAULT_BASE_URL = "https://cloud.uipath.com";
7
7
  /** Auth callback server timeout (5 minutes). */
8
8
  export declare const DEFAULT_AUTH_TIMEOUT_MS: number;
9
+ export declare const AUTH_CANCELLED_ERROR_CODE = "EAUTHCANCELLED";
9
10
  /** Localhost OIDC redirect URI. */
10
11
  export declare const DEFAULT_REDIRECT_URI = "http://localhost:8104/oidc/login";
package/dist/index.d.ts CHANGED
@@ -2,6 +2,7 @@ export * from "./authContext";
2
2
  export * from "./authProfile";
3
3
  export * from "./clientCredentials";
4
4
  export { type AuthFileConfig, InvalidBaseUrlError, setAuthFileConfig, } from "./config";
5
+ export { AUTH_CANCELLED_ERROR_CODE } from "./constants";
5
6
  export { ENFORCE_ROBOT_AUTH_VAR, ENV_AUTH_ENABLE_VAR, ENV_AUTH_VARS, EnvAuthConfigError, isEnvAuthEnabled, isRobotAuthEnforced, readAuthFromEnv, } from "./envAuth";
6
7
  export * from "./interactive";
7
8
  export * from "./loginStatus";
@@ -32,8 +33,11 @@ interface AuthenticateOptions {
32
33
  /** Invoked with the authorize URL when `noBrowser` is set (once, when the
33
34
  * callback server starts listening). Mandatory whenever `noBrowser` is true. */
34
35
  onAuthUrl?: (url: string) => void;
36
+ /** Cancels a stuck browser login: closes the local callback server and
37
+ * rejects with `AUTH_CANCELLED_ERROR_CODE`. Node (local-server) path only. */
38
+ signal?: AbortSignal;
35
39
  }
36
- export declare const authenticate: ({ baseUrl, clientId, clientSecret, redirectUri, scope, organization, timeoutMs, noBrowser, onAuthUrl, }: AuthenticateOptions) => Promise<{
40
+ export declare const authenticate: ({ baseUrl, clientId, clientSecret, redirectUri, scope, organization, timeoutMs, noBrowser, onAuthUrl, signal, }: AuthenticateOptions) => Promise<{
37
41
  accessToken: string;
38
42
  refreshToken: string;
39
43
  }>;
package/dist/index.js CHANGED
@@ -75,7 +75,7 @@ function settlePromiseLike(thenable) {
75
75
  }
76
76
 
77
77
  // src/constants.ts
78
- var UIPATH_HOME_DIR = ".uipath", AUTH_FILENAME = ".auth", DEFAULT_BASE_URL = "https://cloud.uipath.com", DEFAULT_AUTH_TIMEOUT_MS, DEFAULT_REDIRECT_URI = "http://localhost:8104/oidc/login";
78
+ var UIPATH_HOME_DIR = ".uipath", AUTH_FILENAME = ".auth", DEFAULT_BASE_URL = "https://cloud.uipath.com", DEFAULT_AUTH_TIMEOUT_MS, AUTH_CANCELLED_ERROR_CODE = "EAUTHCANCELLED", DEFAULT_REDIRECT_URI = "http://localhost:8104/oidc/login";
79
79
  var init_constants = __esm(() => {
80
80
  DEFAULT_AUTH_TIMEOUT_MS = 5 * 60 * 1000;
81
81
  });
@@ -19318,7 +19318,8 @@ var escapeHtml = (value) => value.replace(/[&<>"']/g, (char) => {
19318
19318
  var AUTH_TIMEOUT_ERROR_CODE = "EAUTHTIMEOUT", startServer = async ({
19319
19319
  redirectUri,
19320
19320
  timeoutMs = DEFAULT_AUTH_TIMEOUT_MS,
19321
- onListening
19321
+ onListening,
19322
+ signal
19322
19323
  }) => {
19323
19324
  let http;
19324
19325
  try {
@@ -19386,8 +19387,24 @@ var AUTH_TIMEOUT_ERROR_CODE = "EAUTHTIMEOUT", startServer = async ({
19386
19387
  reject(new Error("No authorization code received"));
19387
19388
  return;
19388
19389
  });
19389
- const timeoutHandle = setTimeout(() => {
19390
+ let timeoutHandle;
19391
+ const onAbort = () => {
19392
+ clearTimeout(timeoutHandle);
19393
+ server.close();
19394
+ const err = new Error("Authentication cancelled");
19395
+ err.code = AUTH_CANCELLED_ERROR_CODE;
19396
+ reject(err);
19397
+ };
19398
+ if (signal) {
19399
+ if (signal.aborted) {
19400
+ onAbort();
19401
+ return;
19402
+ }
19403
+ signal.addEventListener("abort", onAbort, { once: true });
19404
+ }
19405
+ timeoutHandle = setTimeout(() => {
19390
19406
  server.close();
19407
+ signal?.removeEventListener("abort", onAbort);
19391
19408
  const err = new Error("Authentication timeout");
19392
19409
  err.code = AUTH_TIMEOUT_ERROR_CODE;
19393
19410
  reject(err);
@@ -19395,6 +19412,7 @@ var AUTH_TIMEOUT_ERROR_CODE = "EAUTHTIMEOUT", startServer = async ({
19395
19412
  const bindHost = redirectUri.hostname === "localhost" ? "127.0.0.1" : redirectUri.hostname;
19396
19413
  server.on("error", (err) => {
19397
19414
  clearTimeout(timeoutHandle);
19415
+ signal?.removeEventListener("abort", onAbort);
19398
19416
  reject(err);
19399
19417
  });
19400
19418
  server.listen(Number(redirectUri.port), bindHost, () => {
@@ -19408,6 +19426,7 @@ var AUTH_TIMEOUT_ERROR_CODE = "EAUTHTIMEOUT", startServer = async ({
19408
19426
  });
19409
19427
  server.on("close", () => {
19410
19428
  clearTimeout(timeoutHandle);
19429
+ signal?.removeEventListener("abort", onAbort);
19411
19430
  });
19412
19431
  });
19413
19432
  };
@@ -19422,7 +19441,7 @@ __export(exports_browser_strategy, {
19422
19441
  });
19423
19442
 
19424
19443
  class BrowserAuthStrategy {
19425
- async execute(url, _redirectUri, expectedState, _opts) {
19444
+ async execute(url, _redirectUri, expectedState, opts) {
19426
19445
  const global2 = getGlobalThis();
19427
19446
  if (!global2?.window) {
19428
19447
  throw new Error("Browser environment required for authentication");
@@ -19449,6 +19468,7 @@ class BrowserAuthStrategy {
19449
19468
  ` + "If using an ad blocker, you may need to temporarily disable it.");
19450
19469
  }
19451
19470
  return new Promise((resolve2, reject) => {
19471
+ let timer;
19452
19472
  const messageHandler = (event) => {
19453
19473
  if (event.data?.type === "UIP_AUTH_CODE" && event.data.code) {
19454
19474
  if (event.data.state !== expectedState) {
@@ -19471,13 +19491,30 @@ class BrowserAuthStrategy {
19471
19491
  };
19472
19492
  const cleanup = () => {
19473
19493
  global2.window?.removeEventListener?.("message", messageHandler);
19494
+ opts?.signal?.removeEventListener("abort", onAbort);
19474
19495
  if (timer)
19475
19496
  clearInterval(timer);
19476
19497
  };
19498
+ const onAbort = () => {
19499
+ cleanup();
19500
+ const err = new Error(`Authentication was cancelled.
19501
+
19502
+ ` + "The sign-in was cancelled before completing the login process. " + "Please try again and complete the authentication flow.");
19503
+ err.code = AUTH_CANCELLED_ERROR_CODE;
19504
+ reject(err);
19505
+ popup.close();
19506
+ };
19507
+ if (opts?.signal) {
19508
+ if (opts.signal.aborted) {
19509
+ onAbort();
19510
+ return;
19511
+ }
19512
+ opts.signal.addEventListener("abort", onAbort, { once: true });
19513
+ }
19477
19514
  if (global2.window?.addEventListener) {
19478
19515
  global2.window.addEventListener("message", messageHandler);
19479
19516
  }
19480
- const timer = setInterval(() => {
19517
+ timer = setInterval(() => {
19481
19518
  if (popup.closed) {
19482
19519
  cleanup();
19483
19520
  reject(new Error(`Authentication was cancelled.
@@ -19488,7 +19525,9 @@ class BrowserAuthStrategy {
19488
19525
  });
19489
19526
  }
19490
19527
  }
19491
- var init_browser_strategy = () => {};
19528
+ var init_browser_strategy = __esm(() => {
19529
+ init_constants();
19530
+ });
19492
19531
 
19493
19532
  // src/strategies/node-strategy.ts
19494
19533
  var exports_node_strategy = {};
@@ -19502,6 +19541,7 @@ class NodeAuthStrategy {
19502
19541
  const callbackUrl = await startServer({
19503
19542
  redirectUri,
19504
19543
  timeoutMs: opts?.timeoutMs,
19544
+ signal: opts?.signal,
19505
19545
  onListening: async () => {
19506
19546
  let safeUrl = "";
19507
19547
  for (const ch of url) {
@@ -21511,6 +21551,10 @@ Troubleshooting:` + `
21511
21551
  UIPATH_URL: config.baseUrl
21512
21552
  };
21513
21553
  };
21554
+
21555
+ // src/index.ts
21556
+ init_constants();
21557
+
21514
21558
  // src/interactive.ts
21515
21559
  init_src();
21516
21560
 
@@ -21635,7 +21679,8 @@ var interactiveLoginWithDeps = async (options, deps) => {
21635
21679
  interactive,
21636
21680
  onEvent,
21637
21681
  timeoutMs,
21638
- noBrowser
21682
+ noBrowser,
21683
+ signal
21639
21684
  } = options;
21640
21685
  const emit = (event) => {
21641
21686
  if (!onEvent)
@@ -21677,6 +21722,7 @@ var interactiveLoginWithDeps = async (options, deps) => {
21677
21722
  organization,
21678
21723
  timeoutMs,
21679
21724
  noBrowser,
21725
+ signal,
21680
21726
  onAuthUrl: noBrowser ? (url) => deliverAuthUrl(url) : undefined
21681
21727
  });
21682
21728
  return {
@@ -21829,7 +21875,8 @@ var authenticate = async ({
21829
21875
  organization,
21830
21876
  timeoutMs,
21831
21877
  noBrowser,
21832
- onAuthUrl
21878
+ onAuthUrl,
21879
+ signal
21833
21880
  }) => {
21834
21881
  const config = await resolveConfigAsync({
21835
21882
  customAuthority: baseUrl,
@@ -21879,7 +21926,12 @@ var authenticate = async ({
21879
21926
  const { NodeAuthStrategy: NodeAuthStrategy2 } = await Promise.resolve().then(() => (init_node_strategy(), exports_node_strategy));
21880
21927
  strategy = new NodeAuthStrategy2;
21881
21928
  }
21882
- const code = await strategy.execute(authUrl, effectiveRedirectUriUrl, state, { timeoutMs, noBrowser, onAuthUrl });
21929
+ const code = await strategy.execute(authUrl, effectiveRedirectUriUrl, state, {
21930
+ timeoutMs,
21931
+ noBrowser,
21932
+ onAuthUrl,
21933
+ signal
21934
+ });
21883
21935
  return await exchangeCodeForTokens({
21884
21936
  code,
21885
21937
  codeVerifier: code_verifier,
@@ -21945,7 +21997,8 @@ export {
21945
21997
  ClientCredentialsAuthenticationError,
21946
21998
  AuthProfileValidationError,
21947
21999
  AUTH_TIMEOUT_ERROR_CODE,
21948
- AUTH_FLOW_ENV_VAR
22000
+ AUTH_FLOW_ENV_VAR,
22001
+ AUTH_CANCELLED_ERROR_CODE
21949
22002
  };
21950
22003
 
21951
- //# debugId=0528EAEF2878CFAB64756E2164756E21
22004
+ //# debugId=C5F963336170300664756E2164756E21
@@ -62,6 +62,14 @@ interface InteractiveLoginOptions {
62
62
  * (client-credentials opens no browser).
63
63
  */
64
64
  noBrowser?: boolean;
65
+ /**
66
+ * Cancels a stuck browser login: closes the local callback server, frees
67
+ * the OAuth port immediately, and rejects with `AUTH_CANCELLED_ERROR_CODE`.
68
+ * Lets an in-process host (e.g. the VS Code extension) offer a "Cancel
69
+ * sign-in" affordance instead of forcing the user to wait out `timeoutMs`.
70
+ * Only the authorization-code (browser) path uses it.
71
+ */
72
+ signal?: AbortSignal;
65
73
  }
66
74
  export interface InteractiveLoginDependencies {
67
75
  resolveConfig?: typeof resolveConfigAsync;
package/dist/server.d.ts CHANGED
@@ -3,6 +3,13 @@ interface StartCallbackServerProps {
3
3
  redirectUri: URL;
4
4
  timeoutMs?: number;
5
5
  onListening?: () => Promise<void>;
6
+ /**
7
+ * Aborts the wait for the browser callback. On abort the local server is
8
+ * closed (freeing the port immediately) and the promise rejects with
9
+ * `AUTH_CANCELLED_ERROR_CODE`. Lets an in-process host (e.g. the VS Code
10
+ * extension) cancel a stuck login without waiting out `timeoutMs`.
11
+ */
12
+ signal?: AbortSignal;
6
13
  }
7
- export declare const startServer: ({ redirectUri, timeoutMs, onListening, }: StartCallbackServerProps) => Promise<URL>;
14
+ export declare const startServer: ({ redirectUri, timeoutMs, onListening, signal, }: StartCallbackServerProps) => Promise<URL>;
8
15
  export {};
@@ -12,6 +12,13 @@ export interface AuthExecuteOptions {
12
12
  * listening. Mandatory whenever `noBrowser` is true.
13
13
  */
14
14
  onAuthUrl?: (url: string) => void;
15
+ /**
16
+ * Cancels the in-flight login. The Node strategy closes its local callback
17
+ * server (freeing the port immediately) and rejects with
18
+ * `AUTH_CANCELLED_ERROR_CODE`; the browser strategy closes its popup and
19
+ * rejects. No effect once the flow has already completed.
20
+ */
21
+ signal?: AbortSignal;
15
22
  }
16
23
  export interface IAuthStrategy {
17
24
  execute(url: string, redirectUri: URL, expectedState: string, opts?: AuthExecuteOptions): Promise<string>;
@@ -1,6 +1,4 @@
1
- import type { IAuthStrategy } from "./auth-strategy";
1
+ import type { AuthExecuteOptions, IAuthStrategy } from "./auth-strategy";
2
2
  export declare class BrowserAuthStrategy implements IAuthStrategy {
3
- execute(url: string, _redirectUri: URL, expectedState: string, _opts?: {
4
- timeoutMs?: number;
5
- }): Promise<string>;
3
+ execute(url: string, _redirectUri: URL, expectedState: string, opts?: AuthExecuteOptions): Promise<string>;
6
4
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@uipath/auth",
3
3
  "license": "MIT",
4
- "version": "1.197.0",
4
+ "version": "1.198.0-preview.80",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://github.com/UiPath/cli.git",
@@ -37,5 +37,5 @@
37
37
  "mihaigirleanu",
38
38
  "vlad-uipath"
39
39
  ],
40
- "gitHead": "56f68b263cec4ea1f2a39d738bd99ecf52f88fea"
40
+ "gitHead": "9b2c3c0f21a256d2f38dd28bc97e72e6f7b10a9c"
41
41
  }