@uipath/auth 1.1.0 → 1.196.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,102 @@
1
+ import { getFileSystem } from "@uipath/filesystem";
2
+ import { clientCredentialsLogin } from "./clientCredentials";
3
+ import { resolveConfigAsync } from "./config";
4
+ import { authenticate } from "./index";
5
+ import { type SelectFromList } from "./selectTenant";
6
+ import type { BaseCredentials } from "./types";
7
+ import { loadEnvFileAsync, saveEnvFileAsync } from "./utils/envFile";
8
+ import { assertIssuerMatchesAuthority, parseJWT } from "./utils/jwt";
9
+ /**
10
+ * Structured progress events emitted during interactive login. Auth has no
11
+ * logger of its own (see `refactor(auth): remove common dependency`), so the
12
+ * CLI subscribes to these events and routes them to its logger / output sink.
13
+ */
14
+ export type InteractiveLoginEvent = {
15
+ type: "info";
16
+ message: string;
17
+ } | {
18
+ type: "warn";
19
+ message: string;
20
+ } | {
21
+ type: "saved";
22
+ path: string;
23
+ locality: "local" | "global";
24
+ } | {
25
+ type: "tenant-fetch-failed";
26
+ message: string;
27
+ };
28
+ interface InteractiveLoginOptions {
29
+ envFilePath?: string;
30
+ scope?: string[];
31
+ authority?: string;
32
+ clientId?: string;
33
+ clientSecret?: string;
34
+ tenant?: string;
35
+ organization?: string;
36
+ interactive?: boolean;
37
+ /**
38
+ * Callback used when interactive tenant selection is required (multiple
39
+ * tenants and `interactive` is true). Auth has no UI dependency of its
40
+ * own — the host (e.g. the CLI) supplies the prompt implementation.
41
+ */
42
+ selectFromList?: SelectFromList;
43
+ /** Optional subscriber for user-facing progress events. */
44
+ onEvent?: (event: InteractiveLoginEvent) => void;
45
+ /**
46
+ * Max ms to wait for the browser callback before the local server closes
47
+ * itself and the login rejects with `AUTH_TIMEOUT_ERROR_CODE`. Lets an
48
+ * in-process host (e.g. the VS Code extension) bound a stuck login and
49
+ * free the callback port — parity with the CLI killing its `uip`
50
+ * subprocess on timeout. Defaults to the server's 5-min cap. Only the
51
+ * authorization-code (browser) path uses it.
52
+ */
53
+ timeoutMs?: number;
54
+ }
55
+ export interface InteractiveLoginDependencies {
56
+ resolveConfig?: typeof resolveConfigAsync;
57
+ clientCredentials?: typeof clientCredentialsLogin;
58
+ auth?: typeof authenticate;
59
+ saveEnvFile?: typeof saveEnvFileAsync;
60
+ loadEnvFile?: typeof loadEnvFileAsync;
61
+ getFs?: typeof getFileSystem;
62
+ jwtParser?: typeof parseJWT;
63
+ issuerAsserter?: typeof assertIssuerMatchesAuthority;
64
+ tenantSelector?: (baseUrl: string, accessToken: string, organizationId: string, tenantName?: string, interactive?: boolean) => Promise<[string, string, string]>;
65
+ }
66
+ /**
67
+ * Perform interactive login to UiPath Cloud using either Client Credentials or Authorization Code flow.
68
+ *
69
+ * This function automatically selects the appropriate authentication flow:
70
+ * - If clientSecret is provided: Uses Client Credentials (silent)
71
+ * - Otherwise: Uses Authorization Code with PKCE (opens browser)
72
+ *
73
+ * After successful authentication, credentials are saved to the specified credentials file and
74
+ * the organization ID is extracted from the JWT token.
75
+ *
76
+ * @param options - Login configuration options
77
+ * @param options.envFilePath - Path to save credentials (default: ".uipath/.auth")
78
+ * @param options.scope - OAuth scopes to request (optional)
79
+ * @param options.authority - Custom authority URL (optional)
80
+ * @param options.clientId - Custom client ID (optional)
81
+ * @param options.clientSecret - Client secret for Client Credentials flow (optional)
82
+ * @returns Promise resolving to the saved credentials including access token and organization ID
83
+ *
84
+ * @example
85
+ * ```typescript
86
+ * // Interactive browser-based login
87
+ * const creds = await interactiveLogin({
88
+ * envFilePath: '.uipath/.auth',
89
+ * scope: ['OR.Machines', 'OR.Robots']
90
+ * });
91
+ *
92
+ * // Client Credentials login
93
+ * const creds = await interactiveLogin({
94
+ * envFilePath: '.uipath/.auth',
95
+ * clientId: 'my-app',
96
+ * clientSecret: 'secret-key'
97
+ * });
98
+ * ```
99
+ */
100
+ export declare const interactiveLoginWithDeps: (options: InteractiveLoginOptions, deps: InteractiveLoginDependencies) => Promise<BaseCredentials>;
101
+ export declare const interactiveLogin: (options: InteractiveLoginOptions) => Promise<BaseCredentials>;
102
+ export {};
@@ -0,0 +1,80 @@
1
+ import { getFileSystem } from "@uipath/filesystem";
2
+ import { resolveConfigAsync } from "./config";
3
+ import { tryRobotClientFallback } from "./robotClientFallback";
4
+ import { refreshAccessToken } from "./tokenRefresh";
5
+ import { loadEnvFileAsync, resolveEnvFilePathAsync, saveEnvFileAsync } from "./utils/envFile";
6
+ /**
7
+ * `"Expired"` means no refresh was attempted (no refresh token on file);
8
+ * recovery may be as cheap as copying a file. `"Refresh Failed"` means
9
+ * refresh was tried and could not complete with a usable token.
10
+ */
11
+ export type LoginStatusValue = "Logged in" | "Not logged in" | "Expired" | "Refresh Failed";
12
+ export declare enum LoginStatusSource {
13
+ File = "file",
14
+ Robot = "robot"
15
+ }
16
+ export interface TokenRefreshTelemetry {
17
+ attempted: boolean;
18
+ success: boolean;
19
+ errorMessage?: string;
20
+ }
21
+ export interface LoginStatus {
22
+ loginStatus: LoginStatusValue;
23
+ accessToken?: string;
24
+ refreshToken?: string;
25
+ baseUrl?: string;
26
+ organizationName?: string;
27
+ organizationId?: string;
28
+ tenantName?: string;
29
+ tenantId?: string;
30
+ /**
31
+ * Identity authority derived from the access token's `iss` claim.
32
+ * Authoritative for both cloud (`…/identity_`) and on-prem (`…/identity`),
33
+ * so consumers should build identity URLs from this rather than hardcoding
34
+ * the gateway path. Currently populated only on the Robot-borrow path.
35
+ */
36
+ issuer?: string;
37
+ expiration?: Date;
38
+ hint?: string;
39
+ source?: LoginStatusSource;
40
+ /**
41
+ * True when a refresh rotated successfully at the identity server but
42
+ * persisting the new pair to disk failed. The returned `accessToken` is
43
+ * valid for THIS call; the next invocation will fail until the on-disk
44
+ * pair can be updated.
45
+ */
46
+ persistenceFailed?: boolean;
47
+ /**
48
+ * True when the advisory file lock was acquired during refresh but its
49
+ * release rejected. The refresh outcome itself is unaffected — peers
50
+ * reclaim the leftover lock as stale on their next attempt. Carried as
51
+ * a structured signal so consumers can branch on it without parsing
52
+ * the user-facing `hint`.
53
+ */
54
+ lockReleaseFailed?: boolean;
55
+ tokenRefresh?: TokenRefreshTelemetry;
56
+ }
57
+ export interface GetLoginStatusOptions {
58
+ envFilePath?: string;
59
+ ensureTokenValidityMinutes?: number;
60
+ }
61
+ export interface LoginStatusDependencies {
62
+ resolveEnvFilePath?: typeof resolveEnvFilePathAsync;
63
+ loadEnvFile?: typeof loadEnvFileAsync;
64
+ saveEnvFile?: typeof saveEnvFileAsync;
65
+ getFs?: typeof getFileSystem;
66
+ refreshToken?: typeof refreshAccessToken;
67
+ resolveConfig?: typeof resolveConfigAsync;
68
+ robotFallback?: typeof tryRobotClientFallback;
69
+ }
70
+ /**
71
+ * Get the current login status by reading credentials from the credentials file (with DI for testing)
72
+ */
73
+ export declare const getLoginStatusWithDeps: (options?: GetLoginStatusOptions, deps?: LoginStatusDependencies) => Promise<LoginStatus>;
74
+ /**
75
+ * Get the current login status by reading credentials from the credentials file
76
+ * @param envFilePath - Path to the credentials file (defaults to ".uipath/.auth")
77
+ * @param ensureTokenValidityMinutes - If provided, refreshes the token when it expires within this many minutes
78
+ * @returns LoginStatus object with authentication information
79
+ */
80
+ export declare const getLoginStatusAsync: (options?: GetLoginStatusOptions) => Promise<LoginStatus>;
@@ -0,0 +1,44 @@
1
+ import { getFileSystem } from "@uipath/filesystem";
2
+ import { resolveEnvFilePathAsync } from "./utils/envFile";
3
+ export interface LogoutOptions {
4
+ file?: string;
5
+ }
6
+ export interface LogoutResult {
7
+ success: boolean;
8
+ message: string;
9
+ removedPath?: string;
10
+ reason?: "no_credentials_file";
11
+ }
12
+ /**
13
+ * File system interface for logout operations
14
+ */
15
+ export interface LogoutFileSystem {
16
+ exists: (path: string) => Promise<boolean>;
17
+ rm: (path: string) => Promise<void>;
18
+ }
19
+ /**
20
+ * Dependency injection interface for testing
21
+ */
22
+ export interface LogoutDependencies {
23
+ resolveEnvFilePath?: typeof resolveEnvFilePathAsync;
24
+ getFileSystem?: typeof getFileSystem;
25
+ }
26
+ /**
27
+ * Logout from UiPath Cloud by removing the credentials file.
28
+ *
29
+ * This function removes the credentials file containing authentication credentials.
30
+ * It uses dependency injection for testability.
31
+ *
32
+ * @param options - Logout configuration options
33
+ * @param options.file - Path to credentials file (optional, uses default resolution if not provided)
34
+ * @param deps - Injected dependencies for testing
35
+ * @returns Promise resolving to the logout result
36
+ */
37
+ export declare function logoutWithDeps(options: LogoutOptions, deps?: LogoutDependencies): Promise<LogoutResult>;
38
+ /**
39
+ * Logout from UiPath Cloud by removing the credentials file.
40
+ *
41
+ * @param options - Logout configuration options
42
+ * @returns Promise resolving to the logout result
43
+ */
44
+ export declare function logout(options: LogoutOptions): Promise<LogoutResult>;
package/dist/oidc.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ export declare const getOidcParams: () => Promise<{
2
+ code_verifier: string;
3
+ code_challenge: string;
4
+ state: string;
5
+ }>;
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Minimal structural view of `@uipath/robot-client` — covers only the two
3
+ * methods we consume. Defined locally so that this file compiles even when
4
+ * the package is absent (it is loaded via dynamic `import()` at runtime).
5
+ */
6
+ interface IInteractiveConnectFlow {
7
+ IsEnabled(): Promise<boolean>;
8
+ }
9
+ interface IAccessProvider {
10
+ GetResourceUrl(scope: "Orchestrator"): Promise<string>;
11
+ GetAccessToken(scope: "Orchestrator", refresh: boolean): Promise<string>;
12
+ }
13
+ interface IRobotAgentProxy {
14
+ readonly interactiveConnectFlow: IInteractiveConnectFlow;
15
+ readonly accessProvider: IAccessProvider;
16
+ CloseAsync(): Promise<void>;
17
+ }
18
+ interface RobotClientModule {
19
+ RobotProxyConstructor: new () => IRobotAgentProxy;
20
+ }
21
+ export interface RobotClientFallbackResult {
22
+ accessToken: string;
23
+ baseUrl: string;
24
+ organizationName?: string;
25
+ organizationId?: string;
26
+ tenantName?: string;
27
+ tenantId?: string;
28
+ issuer?: string;
29
+ }
30
+ export interface RobotClientFallbackOptions {
31
+ timeoutMs?: number;
32
+ /** Test seam: report whether the Robot IPC endpoint exists. */
33
+ isRobotIpcAvailable?: () => Promise<boolean>;
34
+ /** Test seam: provide a stubbed module loader. */
35
+ loadModule?: () => Promise<RobotClientModule | undefined>;
36
+ /**
37
+ * When true, skip the soft guards that protect the *default* fallback
38
+ * path: the `UIPATH_URL`-set short-circuit and the CI heuristic. Used by
39
+ * `UIPATH_CLI_ENFORCE_ROBOT_AUTH=true` callers who have explicitly opted
40
+ * into Robot-only auth and accept the IPC handshake cost. Browser is still
41
+ * skipped (no IPC there structurally).
42
+ */
43
+ force?: boolean;
44
+ }
45
+ /**
46
+ * Read credentials from the running UiPath Robot/Assistant via its local IPC.
47
+ *
48
+ * Returns `undefined` — and falls back to the standard "Not logged in" path —
49
+ * when any of the following is true:
50
+ * - running in a browser
51
+ * - `UIPATH_URL` is set (explicit user override takes precedence) — unless
52
+ * `options.force === true`
53
+ * - the process looks like a CI runner (`CI`/`GITHUB_ACTIONS` set) — unless
54
+ * `options.force === true`
55
+ * - `@uipath/robot-client` is not installed or fails to load
56
+ * - Robot is not running, or sign-in is disabled
57
+ * - an IPC call exceeds the timeout
58
+ * - the returned resource URL or access token is malformed/empty
59
+ *
60
+ * Credentials returned by this function are ephemeral: the caller MUST NOT
61
+ * persist them to the auth file.
62
+ */
63
+ export declare const tryRobotClientFallback: (options?: RobotClientFallbackOptions) => Promise<RobotClientFallbackResult | undefined>;
64
+ export {};
@@ -0,0 +1,8 @@
1
+ import { type TenantsAndOrganizations } from "./tenantSelection";
2
+ export type SelectFromList = (options: string[], message: string) => Promise<number>;
3
+ interface TenantSelectionDependencies {
4
+ fetchTenantsAndOrgs?: (baseUrl: string, accessToken: string, organizationId: string) => Promise<TenantsAndOrganizations>;
5
+ selectFromList?: SelectFromList;
6
+ }
7
+ export declare const selectTenantWithDeps: (baseUrl: string, accessToken: string, organizationId: string, targetTenantName?: string, interactive?: boolean, deps?: TenantSelectionDependencies) => Promise<[string, string, string]>;
8
+ export {};
@@ -0,0 +1,8 @@
1
+ export declare const AUTH_TIMEOUT_ERROR_CODE = "EAUTHTIMEOUT";
2
+ interface StartCallbackServerProps {
3
+ redirectUri: URL;
4
+ timeoutMs?: number;
5
+ onListening?: () => Promise<void>;
6
+ }
7
+ export declare const startServer: ({ redirectUri, timeoutMs, onListening, }: StartCallbackServerProps) => Promise<URL>;
8
+ export {};
@@ -0,0 +1,7 @@
1
+ export interface IAuthStrategy {
2
+ execute(url: string, redirectUri: URL, expectedState: string,
3
+ /** Optional controls; `timeoutMs` bounds the wait for the callback. */
4
+ opts?: {
5
+ timeoutMs?: number;
6
+ }): Promise<string>;
7
+ }
@@ -0,0 +1,6 @@
1
+ import type { IAuthStrategy } from "./auth-strategy";
2
+ export declare class BrowserAuthStrategy implements IAuthStrategy {
3
+ execute(url: string, _redirectUri: URL, expectedState: string, _opts?: {
4
+ timeoutMs?: number;
5
+ }): Promise<string>;
6
+ }
@@ -0,0 +1,6 @@
1
+ import type { IAuthStrategy } from "./auth-strategy";
2
+ export declare class NodeAuthStrategy implements IAuthStrategy {
3
+ execute(url: string, redirectUri: URL, expectedState: string, opts?: {
4
+ timeoutMs?: number;
5
+ }): Promise<string>;
6
+ }
@@ -0,0 +1,17 @@
1
+ export interface Tenant {
2
+ id: string;
3
+ name: string;
4
+ [key: string]: unknown;
5
+ }
6
+ interface Organization {
7
+ id: string;
8
+ name: string;
9
+ [key: string]: unknown;
10
+ }
11
+ export interface TenantsAndOrganizations {
12
+ tenants: Tenant[];
13
+ organization: Organization;
14
+ }
15
+ /** Fetch tenants and organizations from UiPath Cloud. */
16
+ export declare const fetchTenantsAndOrganizations: (baseUrl: string, accessToken: string, organizationId: string) => Promise<TenantsAndOrganizations>;
17
+ export {};
@@ -0,0 +1,13 @@
1
+ interface ExchangeCodeForTokensProps {
2
+ code: string;
3
+ codeVerifier: string;
4
+ redirectUri: URL;
5
+ clientId: string;
6
+ clientSecret?: string;
7
+ tokenEndpoint: string;
8
+ }
9
+ export declare const exchangeCodeForTokens: ({ code, codeVerifier, redirectUri, clientId, clientSecret, tokenEndpoint, }: ExchangeCodeForTokensProps) => Promise<{
10
+ accessToken: string;
11
+ refreshToken: string;
12
+ }>;
13
+ export {};
@@ -0,0 +1,27 @@
1
+ interface RefreshTokenParams {
2
+ refreshToken: string;
3
+ tokenEndpoint: string;
4
+ clientId: string;
5
+ /**
6
+ * The authority that originally minted the token (e.g.
7
+ * `https://cloud.uipath.com`). When provided, the refreshed access
8
+ * token's `iss` claim is validated against `<authority>/identity_`
9
+ * to defend against a token endpoint that has been swapped or
10
+ * MITM'd between sessions to issue tokens from a foreign IdP.
11
+ */
12
+ expectedAuthority?: string;
13
+ }
14
+ interface TokenResponse {
15
+ accessToken: string;
16
+ refreshToken: string;
17
+ }
18
+ export declare class TokenRefreshOAuthError extends Error {
19
+ readonly __brand = "TokenRefreshOAuthError";
20
+ constructor();
21
+ }
22
+ export declare function isTokenRefreshOAuthFailure(error: unknown): boolean;
23
+ /**
24
+ * Refresh an access token using a refresh token
25
+ */
26
+ export declare const refreshAccessToken: ({ refreshToken, tokenEndpoint, clientId, expectedAuthority, }: RefreshTokenParams) => Promise<TokenResponse>;
27
+ export {};
@@ -0,0 +1,5 @@
1
+ export interface BaseCredentials {
2
+ UIPATH_ACCESS_TOKEN: string;
3
+ UIPATH_REFRESH_TOKEN?: string;
4
+ [key: string]: string | undefined;
5
+ }
@@ -0,0 +1,106 @@
1
+ export declare const DEFAULT_AUTH_FILENAME = ".auth";
2
+ export declare const DEFAULT_ENV_FILENAME = ".uipath/.auth";
3
+ interface LoadEnvFileProps {
4
+ envPath: string;
5
+ }
6
+ interface SaveEnvFileProps {
7
+ envPath: string;
8
+ data: Record<string, string | undefined>;
9
+ merge?: boolean;
10
+ }
11
+ interface ResolveEnvFilePathResult {
12
+ absolutePath: string | undefined;
13
+ errorMessage?: string;
14
+ }
15
+ export type EnvFileSource = "absolute" | "cwd" | "ancestor" | "home" | "default";
16
+ /**
17
+ * Why the candidate at {@link EnvFileLocation.absolutePath} is not a usable
18
+ * credentials file. Surfaced so callers can tell "file is missing" (run
19
+ * `uip login`) apart from "file exists but cannot be read" (fix permissions
20
+ * or unblock the path) — the older `exists: boolean` API silently collapsed
21
+ * both into `false` and made permission errors look like a fresh install.
22
+ */
23
+ export type EnvFileUnusableReason =
24
+ /** stat() threw — typically EACCES, EPERM, ELOOP, broken symlink. */
25
+ "unreadable"
26
+ /** Path resolves to a directory, not a regular file. */
27
+ | "not-a-file";
28
+ /**
29
+ * Bounded set of `unusable.code` values the resolver can produce. Errno
30
+ * codes from filesystem rejections that fall outside this list are
31
+ * narrowed to `"EUNKNOWN"` rather than passed through verbatim — that
32
+ * keeps the public surface stable as new POSIX errnos appear.
33
+ */
34
+ export type EnvFileErrorCode = "EISDIR" | "EACCES" | "EPERM" | "ELOOP" | "ENOTDIR" | "EUNKNOWN";
35
+ export interface EnvFileUnusable {
36
+ readonly reason: EnvFileUnusableReason;
37
+ readonly code: EnvFileErrorCode;
38
+ readonly message: string;
39
+ }
40
+ /**
41
+ * Discriminated on `exists`. The `exists: true` branch can never carry an
42
+ * `unusable` block, and `source: "default"` only appears on the
43
+ * `exists: false` branch — both invariants are codified in the type so a
44
+ * buggy producer cannot construct an impossible state.
45
+ */
46
+ export type EnvFileLocation = {
47
+ readonly exists: true;
48
+ readonly absolutePath: string;
49
+ readonly source: Exclude<EnvFileSource, "default">;
50
+ } | {
51
+ readonly exists: false;
52
+ readonly absolutePath: string;
53
+ readonly source: EnvFileSource;
54
+ /**
55
+ * Set when the resolver picked this candidate but it is not a
56
+ * usable regular file. Absent when the file is simply missing
57
+ * (ENOENT). When set, `code`/`message` are the underlying
58
+ * filesystem error.
59
+ */
60
+ readonly unusable?: EnvFileUnusable;
61
+ };
62
+ /**
63
+ * Locate the credentials file the CLI would use, without requiring it to
64
+ * exist. Search order: absolute path → walk up from cwd → ~/ fallback.
65
+ * Designed for tools that need to register watchers, cache keys, or status
66
+ * displays before the user has authenticated. Never reads file contents.
67
+ *
68
+ * Uses `fs.stat` (not `fs.exists`) so a candidate that exists but is
69
+ * unreadable (EACCES) or is a directory is reported with `exists: false`
70
+ * **and** an `unusable` block — callers can branch on `unusable.reason`
71
+ * to distinguish "fresh install" from "permissions broken".
72
+ *
73
+ * During cwd walk-up an unreadable/directory candidate is treated as
74
+ * "not found" and the search continues; only the final candidate (the
75
+ * one actually returned) carries the `unusable` block.
76
+ */
77
+ export declare const resolveEnvFileLocationAsync: (envFilePath?: string, opts?: {
78
+ cwd?: string;
79
+ }) => Promise<EnvFileLocation>;
80
+ /**
81
+ * Resolve the absolute path to an environment file, returning an
82
+ * `errorMessage` if no existing usable file was found. Delegates the
83
+ * search (absolute → cwd walk-up → ~/ fallback) and the regular-file
84
+ * check to {@link resolveEnvFileLocationAsync}; see there for full
85
+ * semantics including the unreadable-vs-missing distinction.
86
+ *
87
+ * @param envFilePath - Path to the credentials file (defaults to ".uipath/.auth")
88
+ * @param opts.cwd - Directory to start the relative-path walk-up from (defaults to the process cwd)
89
+ */
90
+ export declare const resolveEnvFilePathAsync: (envFilePath?: string, opts?: {
91
+ cwd?: string;
92
+ }) => Promise<ResolveEnvFilePathResult>;
93
+ /**
94
+ * Load environment variables from a credentials file
95
+ * @param envPath - Path to the credentials file (relative to cwd or absolute)
96
+ * @returns Object with environment variables
97
+ */
98
+ export declare const loadEnvFileAsync: ({ envPath }: LoadEnvFileProps) => Promise<Record<string, string>>;
99
+ /**
100
+ * Save environment variables to a credentials file atomically
101
+ * @param envPath - Path to the credentials file (relative to cwd or absolute)
102
+ * @param data - Object with environment variables to save
103
+ * @param merge - If true, merge with existing file, otherwise overwrite
104
+ */
105
+ export declare const saveEnvFileAsync: ({ envPath, data, merge, }: SaveEnvFileProps) => Promise<void>;
106
+ export {};
@@ -0,0 +1,43 @@
1
+ interface JWTPayload {
2
+ exp: number;
3
+ iat: number;
4
+ iss?: string;
5
+ sub?: string;
6
+ name?: string;
7
+ preferred_username?: string;
8
+ email?: string;
9
+ first_name?: string;
10
+ last_name?: string;
11
+ prtId?: string;
12
+ organizationId?: string;
13
+ prt_id?: string;
14
+ [key: string]: unknown;
15
+ }
16
+ /**
17
+ * Error thrown when a token's `iss` claim does not identify the
18
+ * authority the CLI thought it was talking to. Defends against OIDC
19
+ * issuer mix-up (RFC 9207) and against silently accepting tokens from
20
+ * an unexpected identity server reached via misconfig or proxy.
21
+ */
22
+ export declare class InvalidIssuerError extends Error {
23
+ readonly expected: string;
24
+ readonly actual: string | undefined;
25
+ constructor(expected: string, actual: string | undefined);
26
+ }
27
+ export declare const parseJWT: (token: string) => JWTPayload;
28
+ /**
29
+ * Verify that a token was issued by the authority the caller intends
30
+ * to trust. Throws {@link InvalidIssuerError} on mismatch, missing
31
+ * claim, or malformed token.
32
+ *
33
+ * UiPath identity servers emit `iss` as `<authority>/identity_` (e.g.
34
+ * authority `https://cloud.uipath.com` → `iss` `https://cloud.uipath.com/identity_`).
35
+ * Trailing slashes on either side are tolerated; everything else is strict.
36
+ */
37
+ export declare const assertIssuerMatchesAuthority: (token: string, authority: string) => void;
38
+ /**
39
+ * Extract the expiration date from a JWT access token.
40
+ * Returns undefined if the token is malformed or has no exp claim.
41
+ */
42
+ export declare const getTokenExpiration: (accessToken: string) => Date | undefined;
43
+ export {};
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Platform detection utilities with proper type guards
3
+ * Use these instead of @ts-expect-error suppressions
4
+ */
5
+ interface BrowserWindow {
6
+ document?: unknown;
7
+ screen?: {
8
+ width: number;
9
+ height: number;
10
+ };
11
+ location?: {
12
+ origin: string;
13
+ };
14
+ open?: (url: string, target: string, features: string) => unknown;
15
+ addEventListener?: (event: string, handler: (event: unknown) => void) => void;
16
+ removeEventListener?: (event: string, handler: (event: unknown) => void) => void;
17
+ }
18
+ interface BrowserDocument {
19
+ createElement?: (tag: string) => unknown;
20
+ }
21
+ /**
22
+ * Check if code is running in a browser environment
23
+ */
24
+ export declare function isBrowser(): boolean;
25
+ /**
26
+ * Check if code is running in Node.js environment
27
+ */
28
+ export declare function isNode(): boolean;
29
+ /**
30
+ * Get the global object safely
31
+ */
32
+ export declare function getGlobalThis(): (typeof globalThis & {
33
+ window?: BrowserWindow;
34
+ document?: BrowserDocument;
35
+ }) | undefined;
36
+ export {};