@uipath/auth 1.198.0 → 1.199.0-preview.104

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/config.d.ts CHANGED
@@ -52,6 +52,7 @@ interface ResolveConfigProps {
52
52
  customAuthority?: string;
53
53
  customClientId?: string;
54
54
  customClientSecret?: string;
55
+ customClientAssertion?: string;
55
56
  customScopes?: string[];
56
57
  }
57
58
  /**
@@ -69,5 +70,5 @@ interface ResolveConfigProps {
69
70
  * Throws {@link InvalidBaseUrlError} on any failure.
70
71
  */
71
72
  export declare const normalizeAndValidateBaseUrl: (rawUrl: string) => string;
72
- export declare const resolveConfigAsync: ({ customAuthority, customClientId, customClientSecret, customScopes, }?: ResolveConfigProps) => Promise<EndpointsConfig>;
73
+ export declare const resolveConfigAsync: ({ customAuthority, customClientId, customClientSecret, customClientAssertion, customScopes, }?: ResolveConfigProps) => Promise<EndpointsConfig>;
73
74
  export {};
@@ -0,0 +1,20 @@
1
+ import type { BaseCredentials } from "./types";
2
+ /**
3
+ * OAuth 2.0 client-assertion type for a JWT bearer token (RFC 7523). The
4
+ * external identity provider's OIDC token is presented under this type in
5
+ * place of a client secret.
6
+ */
7
+ export declare const JWT_BEARER_ASSERTION_TYPE = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer";
8
+ interface FederatedCredentialsLoginProps {
9
+ clientId: string;
10
+ /** The OIDC JWT issued by the external provider (GitHub Actions, etc.). */
11
+ clientAssertion: string;
12
+ scope?: string[];
13
+ authority?: string;
14
+ }
15
+ export declare class FederatedCredentialsAuthenticationError extends Error {
16
+ readonly status: number;
17
+ constructor(message: string, status: number);
18
+ }
19
+ export declare const federatedCredentialsLogin: ({ clientId, clientAssertion, scope, authority, }: FederatedCredentialsLoginProps) => Promise<BaseCredentials>;
20
+ export {};
@@ -8,4 +8,5 @@ export { fetchTenantsAndOrganizations, type Tenant, type TenantsAndOrganizations
8
8
  export * from "./tokenRefresh";
9
9
  export { AUTH_FLOW_ENV_VAR, type AuthFlow, type BaseCredentials, } from "./types";
10
10
  export { DEFAULT_AUTH_FILENAME, DEFAULT_ENV_FILENAME, type EnvFileErrorCode, type EnvFileLocation, type EnvFileSource, type EnvFileUnusable, type EnvFileUnusableReason, loadEnvFileAsync, resolveEnvFileLocationAsync, resolveEnvFilePathAsync, saveEnvFileAsync, } from "./utils/envFile";
11
+ export { parseJWT } from "./utils/jwt";
11
12
  export { isBrowser, isNode } from "./utils/platform";
@@ -18335,6 +18335,7 @@ var resolveConfigAsync = async ({
18335
18335
  customAuthority,
18336
18336
  customClientId,
18337
18337
  customClientSecret,
18338
+ customClientAssertion,
18338
18339
  customScopes
18339
18340
  } = {}) => {
18340
18341
  const fileAuth = getAuthFileConfig();
@@ -18360,7 +18361,7 @@ var resolveConfigAsync = async ({
18360
18361
  if (!clientSecret && fileAuth.clientSecret) {
18361
18362
  clientSecret = fileAuth.clientSecret;
18362
18363
  }
18363
- const isExternalAppAuth = clientId !== DEFAULT_CLIENT_ID && Boolean(clientSecret);
18364
+ const isExternalAppAuth = clientId !== DEFAULT_CLIENT_ID && (Boolean(clientSecret) || Boolean(customClientAssertion));
18364
18365
  const scopes = resolveScopes(isExternalAppAuth, customScopes, fileAuth.scopes);
18365
18366
  return {
18366
18367
  clientId,
@@ -19446,6 +19447,49 @@ var getAuthEnv = async (options = {}) => {
19446
19447
  }
19447
19448
  return { authEnv, loginStatus: status };
19448
19449
  };
19450
+ // src/tokenGrant.ts
19451
+ var requestClientCredentialsToken = async ({
19452
+ tokenEndpoint,
19453
+ baseUrl,
19454
+ params,
19455
+ buildError
19456
+ }) => {
19457
+ const tokenResponse = await fetch(tokenEndpoint, {
19458
+ method: "POST",
19459
+ headers: {
19460
+ "Content-Type": "application/x-www-form-urlencoded"
19461
+ },
19462
+ body: new URLSearchParams(params)
19463
+ });
19464
+ const [parseError, tokenData] = await catchError(tokenResponse.json());
19465
+ if (!tokenResponse.ok) {
19466
+ const data = parseError ? {} : tokenData ?? {};
19467
+ throw buildError({
19468
+ status: tokenResponse.status,
19469
+ errorType: data.error || "authentication_failed",
19470
+ errorDesc: data.error_description || "Unknown error"
19471
+ });
19472
+ }
19473
+ if (parseError || !tokenData) {
19474
+ throw buildError({
19475
+ status: tokenResponse.status,
19476
+ errorType: "invalid_response",
19477
+ errorDesc: "Token endpoint returned a non-JSON response."
19478
+ });
19479
+ }
19480
+ if (!tokenData.access_token) {
19481
+ throw buildError({
19482
+ status: tokenResponse.status,
19483
+ errorType: "invalid_response",
19484
+ errorDesc: "Token endpoint response did not include an access_token."
19485
+ });
19486
+ }
19487
+ return {
19488
+ UIPATH_ACCESS_TOKEN: tokenData.access_token,
19489
+ UIPATH_URL: baseUrl
19490
+ };
19491
+ };
19492
+
19449
19493
  // src/clientCredentials.ts
19450
19494
  class ClientCredentialsAuthenticationError extends Error {
19451
19495
  status;
@@ -19455,6 +19499,31 @@ class ClientCredentialsAuthenticationError extends Error {
19455
19499
  this.status = status;
19456
19500
  }
19457
19501
  }
19502
+ var buildClientCredentialsError = ({
19503
+ status,
19504
+ errorType,
19505
+ errorDesc
19506
+ }) => {
19507
+ let troubleshooting = "";
19508
+ if (errorType === "invalid_client" || status === 401) {
19509
+ troubleshooting = `
19510
+
19511
+ Troubleshooting:` + `
19512
+ • Verify your Client ID is correct` + `
19513
+ • Ensure your Client Secret hasn't expired` + `
19514
+ • Check that the external application is enabled in UiPath` + `
19515
+ • Confirm you're using the correct authority URL`;
19516
+ } else if (errorType === "invalid_scope") {
19517
+ troubleshooting = `
19518
+
19519
+ Troubleshooting:` + `
19520
+ • The requested scopes may not be available for your account` + `
19521
+ • Try using default scopes or contact your UiPath administrator`;
19522
+ }
19523
+ return new ClientCredentialsAuthenticationError(`Client Credentials authentication failed (${status})
19524
+ ` + `Error: ${errorType}
19525
+ ` + `Details: ${errorDesc}${troubleshooting}`, status);
19526
+ };
19458
19527
  var clientCredentialsLogin = async ({
19459
19528
  clientId,
19460
19529
  clientSecret,
@@ -19475,41 +19544,12 @@ var clientCredentialsLogin = async ({
19475
19544
  if (config.scopes.length > 0) {
19476
19545
  params.scope = config.scopes.join(" ");
19477
19546
  }
19478
- const tokenResponse = await fetch(config.tokenEndpoint, {
19479
- method: "POST",
19480
- headers: {
19481
- "Content-Type": "application/x-www-form-urlencoded"
19482
- },
19483
- body: new URLSearchParams(params)
19547
+ return await requestClientCredentialsToken({
19548
+ tokenEndpoint: config.tokenEndpoint,
19549
+ baseUrl: config.baseUrl,
19550
+ params,
19551
+ buildError: buildClientCredentialsError
19484
19552
  });
19485
- const tokenData = await tokenResponse.json();
19486
- if (!tokenResponse.ok) {
19487
- const errorType = tokenData.error || "authentication_failed";
19488
- const errorDesc = tokenData.error_description || "Unknown error";
19489
- let troubleshooting = "";
19490
- if (errorType === "invalid_client" || tokenResponse.status === 401) {
19491
- troubleshooting = `
19492
-
19493
- Troubleshooting:` + `
19494
- • Verify your Client ID is correct` + `
19495
- • Ensure your Client Secret hasn't expired` + `
19496
- • Check that the external application is enabled in UiPath` + `
19497
- • Confirm you're using the correct authority URL`;
19498
- } else if (errorType === "invalid_scope") {
19499
- troubleshooting = `
19500
-
19501
- Troubleshooting:` + `
19502
- • The requested scopes may not be available for your account` + `
19503
- • Try using default scopes or contact your UiPath administrator`;
19504
- }
19505
- throw new ClientCredentialsAuthenticationError(`Client Credentials authentication failed (${tokenResponse.status})
19506
- ` + `Error: ${errorType}
19507
- ` + `Details: ${errorDesc}${troubleshooting}`, tokenResponse.status);
19508
- }
19509
- return {
19510
- UIPATH_ACCESS_TOKEN: tokenData.access_token,
19511
- UIPATH_URL: config.baseUrl
19512
- };
19513
19553
  };
19514
19554
  // src/logout.ts
19515
19555
  import { getFileSystem as getFileSystem6 } from "@uipath/filesystem";
@@ -19583,6 +19623,7 @@ export {
19583
19623
  resolveEnvFileLocationAsync,
19584
19624
  resolveAuthProfileFilePath,
19585
19625
  refreshAccessToken,
19626
+ parseJWT,
19586
19627
  normalizeAuthProfileName,
19587
19628
  logoutWithDeps,
19588
19629
  logout,
@@ -19610,4 +19651,4 @@ export {
19610
19651
  AUTH_FLOW_ENV_VAR
19611
19652
  };
19612
19653
 
19613
- //# debugId=08C6C8374F27923B64756E2164756E21
19654
+ //# debugId=34E22CDEA296620564756E2164756E21
package/dist/index.d.ts CHANGED
@@ -4,6 +4,7 @@ export * from "./clientCredentials";
4
4
  export { type AuthFileConfig, InvalidBaseUrlError, setAuthFileConfig, } from "./config";
5
5
  export { AUTH_CANCELLED_ERROR_CODE } from "./constants";
6
6
  export { ENFORCE_ROBOT_AUTH_VAR, ENV_AUTH_ENABLE_VAR, ENV_AUTH_VARS, EnvAuthConfigError, isEnvAuthEnabled, isRobotAuthEnforced, readAuthFromEnv, } from "./envAuth";
7
+ export { FederatedCredentialsAuthenticationError, federatedCredentialsLogin, JWT_BEARER_ASSERTION_TYPE, } from "./federatedCredentials";
7
8
  export * from "./interactive";
8
9
  export * from "./loginStatus";
9
10
  export * from "./logout";
package/dist/index.js CHANGED
@@ -19647,6 +19647,7 @@ var resolveConfigAsync = async ({
19647
19647
  customAuthority,
19648
19648
  customClientId,
19649
19649
  customClientSecret,
19650
+ customClientAssertion,
19650
19651
  customScopes
19651
19652
  } = {}) => {
19652
19653
  const fileAuth = getAuthFileConfig();
@@ -19672,7 +19673,7 @@ var resolveConfigAsync = async ({
19672
19673
  if (!clientSecret && fileAuth.clientSecret) {
19673
19674
  clientSecret = fileAuth.clientSecret;
19674
19675
  }
19675
- const isExternalAppAuth = clientId !== DEFAULT_CLIENT_ID && Boolean(clientSecret);
19676
+ const isExternalAppAuth = clientId !== DEFAULT_CLIENT_ID && (Boolean(clientSecret) || Boolean(customClientAssertion));
19676
19677
  const scopes = resolveScopes(isExternalAppAuth, customScopes, fileAuth.scopes);
19677
19678
  return {
19678
19679
  clientId,
@@ -21486,6 +21487,49 @@ var getAuthEnv = async (options = {}) => {
21486
21487
  }
21487
21488
  return { authEnv, loginStatus: status };
21488
21489
  };
21490
+ // src/tokenGrant.ts
21491
+ var requestClientCredentialsToken = async ({
21492
+ tokenEndpoint,
21493
+ baseUrl,
21494
+ params,
21495
+ buildError
21496
+ }) => {
21497
+ const tokenResponse = await fetch(tokenEndpoint, {
21498
+ method: "POST",
21499
+ headers: {
21500
+ "Content-Type": "application/x-www-form-urlencoded"
21501
+ },
21502
+ body: new URLSearchParams(params)
21503
+ });
21504
+ const [parseError, tokenData] = await catchError(tokenResponse.json());
21505
+ if (!tokenResponse.ok) {
21506
+ const data = parseError ? {} : tokenData ?? {};
21507
+ throw buildError({
21508
+ status: tokenResponse.status,
21509
+ errorType: data.error || "authentication_failed",
21510
+ errorDesc: data.error_description || "Unknown error"
21511
+ });
21512
+ }
21513
+ if (parseError || !tokenData) {
21514
+ throw buildError({
21515
+ status: tokenResponse.status,
21516
+ errorType: "invalid_response",
21517
+ errorDesc: "Token endpoint returned a non-JSON response."
21518
+ });
21519
+ }
21520
+ if (!tokenData.access_token) {
21521
+ throw buildError({
21522
+ status: tokenResponse.status,
21523
+ errorType: "invalid_response",
21524
+ errorDesc: "Token endpoint response did not include an access_token."
21525
+ });
21526
+ }
21527
+ return {
21528
+ UIPATH_ACCESS_TOKEN: tokenData.access_token,
21529
+ UIPATH_URL: baseUrl
21530
+ };
21531
+ };
21532
+
21489
21533
  // src/clientCredentials.ts
21490
21534
  class ClientCredentialsAuthenticationError extends Error {
21491
21535
  status;
@@ -21495,6 +21539,31 @@ class ClientCredentialsAuthenticationError extends Error {
21495
21539
  this.status = status;
21496
21540
  }
21497
21541
  }
21542
+ var buildClientCredentialsError = ({
21543
+ status,
21544
+ errorType,
21545
+ errorDesc
21546
+ }) => {
21547
+ let troubleshooting = "";
21548
+ if (errorType === "invalid_client" || status === 401) {
21549
+ troubleshooting = `
21550
+
21551
+ Troubleshooting:` + `
21552
+ • Verify your Client ID is correct` + `
21553
+ • Ensure your Client Secret hasn't expired` + `
21554
+ • Check that the external application is enabled in UiPath` + `
21555
+ • Confirm you're using the correct authority URL`;
21556
+ } else if (errorType === "invalid_scope") {
21557
+ troubleshooting = `
21558
+
21559
+ Troubleshooting:` + `
21560
+ • The requested scopes may not be available for your account` + `
21561
+ • Try using default scopes or contact your UiPath administrator`;
21562
+ }
21563
+ return new ClientCredentialsAuthenticationError(`Client Credentials authentication failed (${status})
21564
+ ` + `Error: ${errorType}
21565
+ ` + `Details: ${errorDesc}${troubleshooting}`, status);
21566
+ };
21498
21567
  var clientCredentialsLogin = async ({
21499
21568
  clientId,
21500
21569
  clientSecret,
@@ -21515,46 +21584,83 @@ var clientCredentialsLogin = async ({
21515
21584
  if (config.scopes.length > 0) {
21516
21585
  params.scope = config.scopes.join(" ");
21517
21586
  }
21518
- const tokenResponse = await fetch(config.tokenEndpoint, {
21519
- method: "POST",
21520
- headers: {
21521
- "Content-Type": "application/x-www-form-urlencoded"
21522
- },
21523
- body: new URLSearchParams(params)
21587
+ return await requestClientCredentialsToken({
21588
+ tokenEndpoint: config.tokenEndpoint,
21589
+ baseUrl: config.baseUrl,
21590
+ params,
21591
+ buildError: buildClientCredentialsError
21524
21592
  });
21525
- const tokenData = await tokenResponse.json();
21526
- if (!tokenResponse.ok) {
21527
- const errorType = tokenData.error || "authentication_failed";
21528
- const errorDesc = tokenData.error_description || "Unknown error";
21529
- let troubleshooting = "";
21530
- if (errorType === "invalid_client" || tokenResponse.status === 401) {
21531
- troubleshooting = `
21593
+ };
21594
+
21595
+ // src/index.ts
21596
+ init_constants();
21597
+
21598
+ // src/federatedCredentials.ts
21599
+ var JWT_BEARER_ASSERTION_TYPE = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer";
21600
+
21601
+ class FederatedCredentialsAuthenticationError extends Error {
21602
+ status;
21603
+ constructor(message, status) {
21604
+ super(message);
21605
+ this.name = "FederatedCredentialsAuthenticationError";
21606
+ this.status = status;
21607
+ }
21608
+ }
21609
+ var buildFederatedError = ({
21610
+ status,
21611
+ errorType,
21612
+ errorDesc
21613
+ }) => {
21614
+ let troubleshooting = "";
21615
+ if (errorType === "invalid_client" || errorType === "invalid_grant" || errorType === "invalid_request" || status === 401) {
21616
+ troubleshooting = `
21532
21617
 
21533
21618
  Troubleshooting:` + `
21534
- • Verify your Client ID is correct` + `
21535
- Ensure your Client Secret hasn't expired` + `
21536
- Check that the external application is enabled in UiPath` + `
21619
+ • Verify your Client ID matches the external application` + `
21620
+ Confirm a federated credential is registered on the app whose` + `
21621
+ issuer, audience, and subject exactly match the token's claims` + `
21622
+ (list them: uip admin external-apps federated-credentials list <client-id>)` + `
21623
+ • Check the token was issued by the expected provider and has not expired` + `
21537
21624
  • Confirm you're using the correct authority URL`;
21538
- } else if (errorType === "invalid_scope") {
21539
- troubleshooting = `
21625
+ } else if (errorType === "invalid_scope") {
21626
+ troubleshooting = `
21540
21627
 
21541
21628
  Troubleshooting:` + `
21542
- • The requested scopes may not be available for your account` + `
21629
+ • The requested scopes may not be available for your application` + `
21543
21630
  • Try using default scopes or contact your UiPath administrator`;
21544
- }
21545
- throw new ClientCredentialsAuthenticationError(`Client Credentials authentication failed (${tokenResponse.status})
21546
- ` + `Error: ${errorType}
21547
- ` + `Details: ${errorDesc}${troubleshooting}`, tokenResponse.status);
21548
21631
  }
21549
- return {
21550
- UIPATH_ACCESS_TOKEN: tokenData.access_token,
21551
- UIPATH_URL: config.baseUrl
21632
+ return new FederatedCredentialsAuthenticationError(`Federated Credentials authentication failed (${status})
21633
+ ` + `Error: ${errorType}
21634
+ ` + `Details: ${errorDesc}${troubleshooting}`, status);
21635
+ };
21636
+ var federatedCredentialsLogin = async ({
21637
+ clientId,
21638
+ clientAssertion,
21639
+ scope,
21640
+ authority
21641
+ }) => {
21642
+ const config = await resolveConfigAsync({
21643
+ customAuthority: authority,
21644
+ customClientId: clientId,
21645
+ customClientAssertion: clientAssertion,
21646
+ customScopes: scope
21647
+ });
21648
+ const params = {
21649
+ grant_type: "client_credentials",
21650
+ client_id: config.clientId,
21651
+ client_assertion: clientAssertion,
21652
+ client_assertion_type: JWT_BEARER_ASSERTION_TYPE
21552
21653
  };
21654
+ if (config.scopes.length > 0) {
21655
+ params.scope = config.scopes.join(" ");
21656
+ }
21657
+ return await requestClientCredentialsToken({
21658
+ tokenEndpoint: config.tokenEndpoint,
21659
+ baseUrl: config.baseUrl,
21660
+ params,
21661
+ buildError: buildFederatedError
21662
+ });
21553
21663
  };
21554
-
21555
- // src/index.ts
21556
- init_constants();
21557
-
21558
21664
  // src/interactive.ts
21559
21665
  init_src();
21560
21666
 
@@ -21660,6 +21766,7 @@ var interactiveLoginWithDeps = async (options, deps) => {
21660
21766
  const {
21661
21767
  resolveConfig = resolveConfigAsync,
21662
21768
  clientCredentials = clientCredentialsLogin,
21769
+ federatedCredentials = federatedCredentialsLogin,
21663
21770
  auth = authenticate,
21664
21771
  saveEnvFile = saveEnvFileAsync,
21665
21772
  loadEnvFile = loadEnvFileAsync,
@@ -21674,6 +21781,7 @@ var interactiveLoginWithDeps = async (options, deps) => {
21674
21781
  authority,
21675
21782
  clientId,
21676
21783
  clientSecret,
21784
+ clientAssertion,
21677
21785
  tenant,
21678
21786
  organization,
21679
21787
  interactive,
@@ -21699,14 +21807,22 @@ var interactiveLoginWithDeps = async (options, deps) => {
21699
21807
  const config = await resolveConfig({
21700
21808
  customAuthority: authority,
21701
21809
  customClientId: clientId,
21702
- customClientSecret: clientSecret
21810
+ customClientSecret: clientSecret,
21811
+ customClientAssertion: clientAssertion
21703
21812
  });
21704
21813
  const { clientSecret: resolvedSecret } = config;
21705
- if (noBrowser && !resolvedSecret && !onEvent) {
21814
+ if (noBrowser && !resolvedSecret && !clientAssertion && !onEvent) {
21706
21815
  throw new Error("noBrowser login requires an onEvent subscriber to receive the " + "auth-url event — the authorize URL is delivered through it.");
21707
21816
  }
21708
- const authFlow = resolvedSecret ? "client_credentials" : "authorization_code";
21709
- const authPromise = resolvedSecret ? (async () => {
21817
+ const authFlow = clientAssertion ? "federated_credentials" : resolvedSecret ? "client_credentials" : "authorization_code";
21818
+ const authPromise = clientAssertion ? (async () => {
21819
+ return await federatedCredentials({
21820
+ clientId: config.clientId,
21821
+ clientAssertion,
21822
+ authority: config.baseUrl,
21823
+ scope
21824
+ });
21825
+ })() : resolvedSecret ? (async () => {
21710
21826
  return await clientCredentials({
21711
21827
  clientId: config.clientId,
21712
21828
  clientSecret: resolvedSecret,
@@ -21740,6 +21856,9 @@ var interactiveLoginWithDeps = async (options, deps) => {
21740
21856
  UIPATH_URL: config.baseUrl,
21741
21857
  [AUTH_FLOW_ENV_VAR]: authFlow
21742
21858
  };
21859
+ if (authFlow !== "authorization_code") {
21860
+ credentials.UIPATH_REFRESH_TOKEN = undefined;
21861
+ }
21743
21862
  try {
21744
21863
  const tokenData = jwtParser(tokens.UIPATH_ACCESS_TOKEN);
21745
21864
  const orgId = tokenData.prtId || tokenData.organizationId || tokenData.prt_id;
@@ -21975,6 +22094,7 @@ export {
21975
22094
  getActiveAuthProfileFilePath,
21976
22095
  getActiveAuthProfile,
21977
22096
  fetchTenantsAndOrganizations,
22097
+ federatedCredentialsLogin,
21978
22098
  clientCredentialsLogin,
21979
22099
  clearRefreshBreaker,
21980
22100
  clearActiveAuthProfile,
@@ -21984,9 +22104,11 @@ export {
21984
22104
  TenantSelectionError,
21985
22105
  TENANT_SELECTION_REQUIRED_CODE,
21986
22106
  LoginStatusSource,
22107
+ JWT_BEARER_ASSERTION_TYPE,
21987
22108
  InvalidTenantError,
21988
22109
  InvalidBaseUrlError,
21989
22110
  INVALID_TENANT_CODE,
22111
+ FederatedCredentialsAuthenticationError,
21990
22112
  EnvAuthConfigError,
21991
22113
  ENV_AUTH_VARS,
21992
22114
  ENV_AUTH_ENABLE_VAR,
@@ -22001,4 +22123,4 @@ export {
22001
22123
  AUTH_CANCELLED_ERROR_CODE
22002
22124
  };
22003
22125
 
22004
- //# debugId=C5F963336170300664756E2164756E21
22126
+ //# debugId=66CC81FE55A926CF64756E2164756E21
@@ -1,6 +1,7 @@
1
1
  import { getFileSystem } from "@uipath/filesystem";
2
2
  import { clientCredentialsLogin } from "./clientCredentials";
3
3
  import { resolveConfigAsync } from "./config";
4
+ import { federatedCredentialsLogin } from "./federatedCredentials";
4
5
  import { authenticate } from "./index";
5
6
  import { type SelectFromList } from "./selectTenant";
6
7
  import { type BaseCredentials } from "./types";
@@ -34,6 +35,13 @@ interface InteractiveLoginOptions {
34
35
  authority?: string;
35
36
  clientId?: string;
36
37
  clientSecret?: string;
38
+ /**
39
+ * OIDC token (client assertion) for workload identity federation. When
40
+ * set, the federated flow is used instead of client credentials or the
41
+ * browser flow — the token is exchanged for a UiPath access token and is
42
+ * never persisted. Mutually exclusive with `clientSecret`.
43
+ */
44
+ clientAssertion?: string;
37
45
  tenant?: string;
38
46
  organization?: string;
39
47
  interactive?: boolean;
@@ -74,6 +82,7 @@ interface InteractiveLoginOptions {
74
82
  export interface InteractiveLoginDependencies {
75
83
  resolveConfig?: typeof resolveConfigAsync;
76
84
  clientCredentials?: typeof clientCredentialsLogin;
85
+ federatedCredentials?: typeof federatedCredentialsLogin;
77
86
  auth?: typeof authenticate;
78
87
  saveEnvFile?: typeof saveEnvFileAsync;
79
88
  loadEnvFile?: typeof loadEnvFileAsync;
@@ -0,0 +1,28 @@
1
+ import type { BaseCredentials } from "./types";
2
+ interface RequestTokenProps {
3
+ tokenEndpoint: string;
4
+ baseUrl: string;
5
+ params: Record<string, string>;
6
+ /**
7
+ * Flow-specific error factory. Receives the HTTP status and the parsed
8
+ * OAuth `error` / `error_description` (defaulted) so each flow can render
9
+ * its own message and troubleshooting while sharing the request plumbing.
10
+ */
11
+ buildError: (args: {
12
+ status: number;
13
+ errorType: string;
14
+ errorDesc: string;
15
+ }) => Error;
16
+ }
17
+ /**
18
+ * POST an OAuth 2.0 `client_credentials` token request and return
19
+ * {@link BaseCredentials}. Shared by the secret-based client-credentials flow
20
+ * and the federated (jwt-bearer client-assertion) flow — the only differences
21
+ * are the POST parameters and the error message, both injected by the caller.
22
+ *
23
+ * Parses the response body defensively: a non-JSON body (proxy/WAF HTML, empty
24
+ * body) or a 2xx response missing `access_token` surfaces the flow's friendly
25
+ * error instead of a raw `SyntaxError` or an undefined token leaking downstream.
26
+ */
27
+ export declare const requestClientCredentialsToken: ({ tokenEndpoint, baseUrl, params, buildError, }: RequestTokenProps) => Promise<BaseCredentials>;
28
+ export {};
package/dist/types.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export declare const AUTH_FLOW_ENV_VAR = "UIPATH_AUTH_FLOW";
2
- export type AuthFlow = "authorization_code" | "client_credentials";
2
+ export type AuthFlow = "authorization_code" | "client_credentials" | "federated_credentials";
3
3
  export interface BaseCredentials {
4
4
  UIPATH_ACCESS_TOKEN: string;
5
5
  UIPATH_REFRESH_TOKEN?: string;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@uipath/auth",
3
3
  "license": "MIT",
4
- "version": "1.198.0",
4
+ "version": "1.199.0-preview.104",
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": "1fadf03d7a8dd102742571dff569fdac11808afb"
40
+ "gitHead": "829a8ab8a25bce5b62c284bd1ddc674d2947f647"
41
41
  }