UNPKG

@itwin/itwins-client

Version:

iTwins client for the iTwin platform

168 lines 7.52 kB
import type { AccessToken } from "@itwin/core-bentley"; import type { BentleyAPIResponse, Method, RequestConfig } from "./types/CommonApiTypes"; import { ParameterMapping } from "./types/typeUtils"; /** * Base client class providing common functionality for iTwins API requests. * Handles authentication, request configuration, and query string building, and error validation. */ export declare abstract class BaseBentleyAPIClient { /** * The max redirects for iTwins API endpoints. * The max redirects can be customized via the constructor parameter or automatically * modified based on the IMJS_MAX_REDIRECTS environment variable. * * @readonly */ protected readonly _maxRedirects: number; /** * Creates a new BaseClient instance for API operations * @param maxRedirects - Optional custom max redirects, defaults to 5 * * @example * ```typescript * // Use default max redirects * const client = new BaseClient(); * * // Use custom max redirects * const client = new BaseClient(10); * ``` */ constructor(maxRedirects?: number); /** * Sends a generic API request with type safety and response validation. * Handles authentication, error responses, and data extraction automatically. * Error responses follow APIM standards for consistent error handling. * * @param accessToken - The client access token for authentication * @param method - The HTTP method type (GET, POST, DELETE, etc.) * @param url - The complete URL of the request endpoint * @param data - Optional payload data for the request body * @param headers - Optional additional request headers * @returns Promise that resolves to the parsed API response with type safety */ protected sendGenericAPIRequest<TResponse = unknown, TData = unknown>(accessToken: AccessToken, method: Method, url: string, data?: TData, headers?: Record<string, string>, allowRedirects?: boolean): Promise<BentleyAPIResponse<TResponse>>; /** * Follows redirects using the fetch default 'follow' behavior. * Used for environments where manual redirect returns opaque responses. * * @param requestOptions - The original request options * @returns Promise that resolves to the final API response */ private followRedirectWithFetchFollow; /** * Handles 302 redirect responses by validating and following the redirect. * * @param response - The 302 redirect response * @param accessToken - The client access token * @param method - The HTTP method * @param data - Optional request payload * @param headers - Optional request headers (will be forwarded to redirect) * @param redirectCount - Current redirect depth * @returns Promise that resolves to the final API response */ private followRedirect; /** * Processes a non-redirect HTTP response. * * @param response - The HTTP response to process * @returns Promise that resolves to a typed API response */ private processResponse; /** * Creates a generic internal server error response. * * @returns A 500 error response for internal exceptions */ private createInternalServerError; /** * Verifies that a redirect response is valid and safe to follow. * Performs three critical validations: * 1. Checks redirect count to prevent infinite loops * 2. Ensures Location header is present * 3. Validates redirect URL for security * * @param response - The 302 redirect response to verify * @param redirectCount - Current redirect depth * @returns Verification result with either error or validated redirect URL */ private checkRedirectValidity; /** * Validates that a redirect URL is secure and targets a trusted APIM Bentley domain. * * This method enforces security requirements for following HTTP redirects: * - URL must use HTTPS protocol (not HTTP) * - Domain must be a Bentley-owned domain (*api.bentley.com) * * @param url - The redirect URL to validate * @returns True if the URL is valid and safe to follow * @throws Error if the URL is invalid, uses HTTP, or targets an untrusted domain * * @remarks * This validation is critical for security when following 302 redirects in federated * architecture scenarios. It prevents redirect attacks that could leak authentication * credentials to malicious domains. * * @example * ```typescript * // Valid URLs * this.validateRedirectUrl("https://api.bentley.com/resource"); * // Invalid URLs (will throw) * this.validateRedirectUrl("https://evil-tuna.com/phishing/"); // Non-Bentley domain * this.validateRedirectUrl("https://bentley.com.evil.com/fake"); // Domain spoofing attempt * ``` */ private validateRedirectUrlSecurity; /** * Creates request configuration options with authentication headers. * Validates required parameters and sets up proper content type for JSON requests. * * @param accessTokenString - The client access token string for authorization * @param method - The HTTP method type (GET, POST, DELETE, etc.) * @param url - The complete URL of the request endpoint * @param data - Optional payload data to be JSON stringified for the request body * @param headers - Optional additional request headers to include * @returns RequestConfig object with method, URL, body, and headers configured * @throws Will throw an error if access token or URL are missing/invalid */ protected createRequestOptions<TData>(accessTokenString: string, method: Method, url: string, data?: TData, headers?: Record<string, string>): RequestConfig; /** * Builds a query string to be appended to a URL from query arguments * @param parameterMapping - Parameter mapping configuration that maps object properties to query parameter names * @param queryArg - Object containing queryable properties for filtering * @returns Query string with parameters applied, ready to append to a URL * * @example * ```typescript * const queryString = this.getQueryStringArg( * ITwinsAccess.ITWINS_QUERY_PARAM_MAPPING, * { * search: "Building A", * top: 10, * subClass: "Asset" * } * ); * // Returns: "$search=Building%20A&$top=10&subClass=Asset" * ``` */ protected getQueryStringArg<T>(parameterMapping: ParameterMapping<NonNullable<T>>, queryArg?: T): string; /** * Helper method to build query parameter array from mapping. * Uses exhaustive parameter mapping to ensure type safety and prevent missing parameters. * Automatically handles URL encoding and filters out excluded parameters. * * @param queryArg - Object containing queryable properties * @param mapping - Parameter mapping configuration that maps object properties to query parameter names * @returns Array of formatted query parameter strings ready for URL construction * * @example * ```typescript * const params = this.buildQueryParams( * { search: "Building A", top: 10 }, * { search: "$search", top: "$top" } * ); * // Returns: ["$search=Building%20A", "$top=10"] * ``` */ private buildQueryParams; } //# sourceMappingURL=BaseBentleyAPIClient.d.ts.map