@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 +2 -1
- package/dist/federatedCredentials.d.ts +20 -0
- package/dist/index.browser.d.ts +1 -0
- package/dist/index.browser.js +77 -36
- package/dist/index.d.ts +1 -0
- package/dist/index.js +158 -36
- package/dist/interactive.d.ts +9 -0
- package/dist/tokenGrant.d.ts +28 -0
- package/dist/types.d.ts +1 -1
- package/package.json +2 -2
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 {};
|
package/dist/index.browser.d.ts
CHANGED
|
@@ -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";
|
package/dist/index.browser.js
CHANGED
|
@@ -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
|
-
|
|
19479
|
-
|
|
19480
|
-
|
|
19481
|
-
|
|
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=
|
|
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
|
-
|
|
21519
|
-
|
|
21520
|
-
|
|
21521
|
-
|
|
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
|
-
|
|
21526
|
-
|
|
21527
|
-
|
|
21528
|
-
|
|
21529
|
-
|
|
21530
|
-
|
|
21531
|
-
|
|
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
|
|
21535
|
-
•
|
|
21536
|
-
|
|
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
|
-
|
|
21539
|
-
|
|
21625
|
+
} else if (errorType === "invalid_scope") {
|
|
21626
|
+
troubleshooting = `
|
|
21540
21627
|
|
|
21541
21628
|
Troubleshooting:` + `
|
|
21542
|
-
• The requested scopes may not be available for your
|
|
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
|
-
|
|
21551
|
-
|
|
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 =
|
|
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=
|
|
22126
|
+
//# debugId=66CC81FE55A926CF64756E2164756E21
|
package/dist/interactive.d.ts
CHANGED
|
@@ -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.
|
|
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": "
|
|
40
|
+
"gitHead": "829a8ab8a25bce5b62c284bd1ddc674d2947f647"
|
|
41
41
|
}
|