@@ -3,79 +3,45 @@ export interface HttpHeaders {
33}
44
55/**
6- * Generic interface for handling authentication for HTTP requests.
7- *
8- * - For each HTTP request, this handler is called to provide additional headers to the request through
9- * the headers() function.
10- * - After the server returns a response, the shouldRetryWithHeaders() function is called. Usually this
11- * function responds to a 401 or 403 response or JSON-RPC codes, but can respond to any other signal -
12- * that is an implementation detail of the AuthenticationHandler.
13- * - If the shouldRetryWithHeaders() function returns new headers, then the request should retried with the provided
14- * revised headers. These provisional headers may, or may not, be optimistically stored for subsequent requests -
15- * that is an implementation detail of the AuthenticationHandler.
16- * - If the request is successful and the onSuccessfulRetry() is defined, then the onSuccessfulRetry() function is
17- * called with the headers that were used to successfully complete the request. This callback provides an
18- * opportunity to save the headers for subsequent requests if they were not already saved.
6+ * Pluggable authentication handler for HTTP requests.
197 *
8+ * - {@link headers} is called before each request to supply additional
9+ * request headers (typically `Authorization`).
10+ * - {@link shouldRetryWithHeaders} is called after every response and
11+ * decides whether the request should be retried with new headers,
12+ * typically in response to a 401 / 403 or a WWW-Authenticate.
13+ * - {@link onSuccessfulRetry}, if defined, is called when a retry
14+ * succeeds, giving the handler a chance to persist the new headers.
2015 */
2116export interface AuthenticationHandler {
22- /**
23- * Provides additional HTTP request headers.
24- * @returns HTTP headers which may include Authorization if available.
25- */
17+ /** Returns request headers (may include `Authorization`). */
2618 headers : ( ) => Promise < HttpHeaders > ;
2719
2820 /**
29- * For every HTTP response (even 200s) the shouldRetryWithHeaders() method is called.
30- * This method is supposed to check if the request needs to be retried and if, yes,
31- * return a set of headers. An A2A server might indicate auth failures in its response
32- * by JSON-rpc codes, HTTP codes like 401, 403 or headers like WWW-Authenticate.
33- *
34- * @param req The RequestInit object used to invoke fetch()
35- * @param res The fetch Response object
36- * @returns If the HTTP request should be retried then returns the HTTP headers to use,
37- * or returns undefined if no retry should be made.
21+ * Called for every response. Returns new headers if the request
22+ * should be retried, or `undefined` to skip the retry.
3823 */
3924 shouldRetryWithHeaders : ( req : RequestInit , res : Response ) => Promise < HttpHeaders | undefined > ;
4025
4126 /**
42- * If the last HTTP request using the headers from shouldRetryWithHeaders() was successful, and
43- * this function is implemented, then it will be called with the headers provided from
44- * shouldRetryWithHeaders().
45- *
46- * This callback allows transient headers to be saved for subsequent requests only when they
47- * are validated by the server.
27+ * Called when a retry using the headers from
28+ * {@link shouldRetryWithHeaders} succeeded. Lets the handler persist
29+ * those headers for subsequent requests.
4830 */
4931 onSuccessfulRetry ?: ( headers : HttpHeaders ) => Promise < void > ;
5032}
5133
5234/**
53- * Higher-order function that wraps fetch with authentication handling logic.
54- * Returns a new fetch function that automatically handles authentication retries for 401/403 responses.
55- *
56- * @param fetchImpl The underlying fetch implementation to wrap
57- * @param authHandler Authentication handler for managing auth headers and retries
58- * @returns A new fetch function with authentication handling capabilities
59- *
60- * Usage examples:
61- * - const authFetch = createAuthHandlingFetch(fetch, authHandler);
62- * - const response = await authFetch(url, options);
63- * - const response = await authFetch(url); // Direct function call
35+ * Wraps `fetch` with authentication handling. The returned function
36+ * injects headers from `authHandler.headers()`, retries when
37+ * `authHandler.shouldRetryWithHeaders` returns new headers, and notifies
38+ * via `onSuccessfulRetry` when the retry succeeds.
6439 */
6540export function createAuthenticatingFetchWithRetry (
6641 fetchImpl : typeof fetch ,
6742 authHandler : AuthenticationHandler
6843) : typeof fetch {
69- /**
70- * Executes a fetch request with authentication handling.
71- * If the auth handler provides new headers for the shouldRetryWithHeaders() function,
72- * then the request is retried.
73- * @param url The URL to fetch
74- * @param init The fetch request options
75- * @returns A Promise that resolves to the Response
76- */
7744 async function authFetch ( url : RequestInfo | URL , init ?: RequestInit ) : Promise < Response > {
78- // Merge auth headers with provided headers
7945 const authHeaders = ( await authHandler . headers ( ) ) || { } ;
8046 const mergedInit : RequestInit = {
8147 ...( init || { } ) ,
@@ -87,10 +53,8 @@ export function createAuthenticatingFetchWithRetry(
8753
8854 let response = await fetchImpl ( url , mergedInit ) ;
8955
90- // Check if the auth handler wants to retry the request with new headers
9156 const updatedHeaders = await authHandler . shouldRetryWithHeaders ( mergedInit , response ) ;
9257 if ( updatedHeaders ) {
93- // Retry request with revised headers
9458 const retryInit : RequestInit = {
9559 ...( init || { } ) ,
9660 headers : {
@@ -101,14 +65,14 @@ export function createAuthenticatingFetchWithRetry(
10165 response = await fetchImpl ( url , retryInit ) ;
10266
10367 if ( response . ok && authHandler . onSuccessfulRetry ) {
104- await authHandler . onSuccessfulRetry ( updatedHeaders ) ; // Remember headers that worked
68+ await authHandler . onSuccessfulRetry ( updatedHeaders ) ;
10569 }
10670 }
10771
10872 return response ;
10973 }
11074
111- // Copy fetch properties to maintain compatibility
75+ // Preserve fetch's own properties so the wrapped function is a drop-in.
11276 Object . setPrototypeOf ( authFetch , Object . getPrototypeOf ( fetchImpl ) ) ;
11377 Object . defineProperties ( authFetch , Object . getOwnPropertyDescriptors ( fetchImpl ) ) ;
11478
0 commit comments