Add isSystemRequest support to Kibana Platform (#53734) (#55927)

This commit is contained in:
Josh Dover 2020-01-28 07:33:11 -07:00 committed by GitHub
parent 1b96001fc0
commit 5bbf2cfc59
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
65 changed files with 759 additions and 346 deletions

View file

@ -1,11 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-public](./kibana-plugin-public.md) &gt; [HttpErrorRequest](./kibana-plugin-public.httperrorrequest.md) &gt; [error](./kibana-plugin-public.httperrorrequest.error.md)
## HttpErrorRequest.error property
<b>Signature:</b>
```typescript
error: Error;
```

View file

@ -1,20 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-public](./kibana-plugin-public.md) &gt; [HttpErrorRequest](./kibana-plugin-public.httperrorrequest.md)
## HttpErrorRequest interface
<b>Signature:</b>
```typescript
export interface HttpErrorRequest
```
## Properties
| Property | Type | Description |
| --- | --- | --- |
| [error](./kibana-plugin-public.httperrorrequest.error.md) | <code>Error</code> | |
| [request](./kibana-plugin-public.httperrorrequest.request.md) | <code>Request</code> | |

View file

@ -1,11 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-public](./kibana-plugin-public.md) &gt; [HttpErrorRequest](./kibana-plugin-public.httperrorrequest.md) &gt; [request](./kibana-plugin-public.httperrorrequest.request.md)
## HttpErrorRequest.request property
<b>Signature:</b>
```typescript
request: Request;
```

View file

@ -1,11 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-public](./kibana-plugin-public.md) &gt; [HttpErrorResponse](./kibana-plugin-public.httperrorresponse.md) &gt; [error](./kibana-plugin-public.httperrorresponse.error.md)
## HttpErrorResponse.error property
<b>Signature:</b>
```typescript
error: Error | IHttpFetchError;
```

View file

@ -1,19 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-public](./kibana-plugin-public.md) &gt; [HttpErrorResponse](./kibana-plugin-public.httperrorresponse.md)
## HttpErrorResponse interface
<b>Signature:</b>
```typescript
export interface HttpErrorResponse extends IHttpResponse
```
## Properties
| Property | Type | Description |
| --- | --- | --- |
| [error](./kibana-plugin-public.httperrorresponse.error.md) | <code>Error &#124; IHttpFetchError</code> | |

View file

@ -4,7 +4,7 @@
## HttpFetchOptions.asResponse property
When `true` the return type of [HttpHandler](./kibana-plugin-public.httphandler.md) will be an [IHttpResponse](./kibana-plugin-public.ihttpresponse.md) with detailed request and response information. When `false`<!-- -->, the return type will just be the parsed response body. Defaults to `false`<!-- -->.
When `true` the return type of [HttpHandler](./kibana-plugin-public.httphandler.md) will be an [HttpResponse](./kibana-plugin-public.httpresponse.md) with detailed request and response information. When `false`<!-- -->, the return type will just be the parsed response body. Defaults to `false`<!-- -->.
<b>Signature:</b>

View file

@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-public](./kibana-plugin-public.md) &gt; [HttpFetchOptions](./kibana-plugin-public.httpfetchoptions.md) &gt; [asSystemRequest](./kibana-plugin-public.httpfetchoptions.assystemrequest.md)
## HttpFetchOptions.asSystemRequest property
Whether or not the request should include the "system request" header to differentiate an end user request from Kibana internal request. Can be read on the server-side using KibanaRequest\#isSystemRequest. Defaults to `false`<!-- -->.
<b>Signature:</b>
```typescript
asSystemRequest?: boolean;
```

View file

@ -16,7 +16,8 @@ export interface HttpFetchOptions extends HttpRequestInit
| Property | Type | Description |
| --- | --- | --- |
| [asResponse](./kibana-plugin-public.httpfetchoptions.asresponse.md) | <code>boolean</code> | When <code>true</code> the return type of [HttpHandler](./kibana-plugin-public.httphandler.md) will be an [IHttpResponse](./kibana-plugin-public.ihttpresponse.md) with detailed request and response information. When <code>false</code>, the return type will just be the parsed response body. Defaults to <code>false</code>. |
| [asResponse](./kibana-plugin-public.httpfetchoptions.asresponse.md) | <code>boolean</code> | When <code>true</code> the return type of [HttpHandler](./kibana-plugin-public.httphandler.md) will be an [HttpResponse](./kibana-plugin-public.httpresponse.md) with detailed request and response information. When <code>false</code>, the return type will just be the parsed response body. Defaults to <code>false</code>. |
| [asSystemRequest](./kibana-plugin-public.httpfetchoptions.assystemrequest.md) | <code>boolean</code> | Whether or not the request should include the "system request" header to differentiate an end user request from Kibana internal request. Can be read on the server-side using KibanaRequest\#isSystemRequest. Defaults to <code>false</code>. |
| [headers](./kibana-plugin-public.httpfetchoptions.headers.md) | <code>HttpHeadersInit</code> | Headers to send with the request. See [HttpHeadersInit](./kibana-plugin-public.httpheadersinit.md)<!-- -->. |
| [prependBasePath](./kibana-plugin-public.httpfetchoptions.prependbasepath.md) | <code>boolean</code> | Whether or not the request should automatically prepend the basePath. Defaults to <code>true</code>. |
| [query](./kibana-plugin-public.httpfetchoptions.query.md) | <code>HttpFetchQuery</code> | The query string for an HTTP request. See [HttpFetchQuery](./kibana-plugin-public.httpfetchquery.md)<!-- -->. |

View file

@ -0,0 +1,20 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-public](./kibana-plugin-public.md) &gt; [HttpFetchOptionsWithPath](./kibana-plugin-public.httpfetchoptionswithpath.md)
## HttpFetchOptionsWithPath interface
Similar to [HttpFetchOptions](./kibana-plugin-public.httpfetchoptions.md) but with the URL path included.
<b>Signature:</b>
```typescript
export interface HttpFetchOptionsWithPath extends HttpFetchOptions
```
## Properties
| Property | Type | Description |
| --- | --- | --- |
| [path](./kibana-plugin-public.httpfetchoptionswithpath.path.md) | <code>string</code> | |

View file

@ -0,0 +1,11 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-public](./kibana-plugin-public.md) &gt; [HttpFetchOptionsWithPath](./kibana-plugin-public.httpfetchoptionswithpath.md) &gt; [path](./kibana-plugin-public.httpfetchoptionswithpath.path.md)
## HttpFetchOptionsWithPath.path property
<b>Signature:</b>
```typescript
path: string;
```

View file

@ -4,7 +4,7 @@
## HttpHandler interface
A function for making an HTTP requests to Kibana's backend. See [HttpFetchOptions](./kibana-plugin-public.httpfetchoptions.md) for options and [IHttpResponse](./kibana-plugin-public.ihttpresponse.md) for the response.
A function for making an HTTP requests to Kibana's backend. See [HttpFetchOptions](./kibana-plugin-public.httpfetchoptions.md) for options and [HttpResponse](./kibana-plugin-public.httpresponse.md) for the response.
<b>Signature:</b>

View file

@ -4,6 +4,7 @@
## HttpHeadersInit interface
Headers to append to the request. Any headers that begin with `kbn-` are considered private to Core and will cause [HttpHandler](./kibana-plugin-public.httphandler.md) to throw an error.
<b>Signature:</b>

View file

@ -16,7 +16,7 @@ export interface HttpInterceptor
| Method | Description |
| --- | --- |
| [request(request, controller)](./kibana-plugin-public.httpinterceptor.request.md) | Define an interceptor to be executed before a request is sent. |
| [request(fetchOptions, controller)](./kibana-plugin-public.httpinterceptor.request.md) | Define an interceptor to be executed before a request is sent. |
| [requestError(httpErrorRequest, controller)](./kibana-plugin-public.httpinterceptor.requesterror.md) | Define an interceptor to be executed if a request interceptor throws an error or returns a rejected Promise. |
| [response(httpResponse, controller)](./kibana-plugin-public.httpinterceptor.response.md) | Define an interceptor to be executed after a response is received. |
| [responseError(httpErrorResponse, controller)](./kibana-plugin-public.httpinterceptor.responseerror.md) | Define an interceptor to be executed if a response interceptor throws an error or returns a rejected Promise. |

View file

@ -9,17 +9,17 @@ Define an interceptor to be executed before a request is sent.
<b>Signature:</b>
```typescript
request?(request: Request, controller: IHttpInterceptController): Promise<Request> | Request | void;
request?(fetchOptions: Readonly<HttpFetchOptionsWithPath>, controller: IHttpInterceptController): MaybePromise<Partial<HttpFetchOptionsWithPath>> | void;
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| request | <code>Request</code> | |
| fetchOptions | <code>Readonly&lt;HttpFetchOptionsWithPath&gt;</code> | |
| controller | <code>IHttpInterceptController</code> | |
<b>Returns:</b>
`Promise<Request> | Request | void`
`MaybePromise<Partial<HttpFetchOptionsWithPath>> | void`

View file

@ -9,17 +9,17 @@ Define an interceptor to be executed if a request interceptor throws an error or
<b>Signature:</b>
```typescript
requestError?(httpErrorRequest: HttpErrorRequest, controller: IHttpInterceptController): Promise<Request> | Request | void;
requestError?(httpErrorRequest: HttpInterceptorRequestError, controller: IHttpInterceptController): MaybePromise<Partial<HttpFetchOptionsWithPath>> | void;
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| httpErrorRequest | <code>HttpErrorRequest</code> | |
| httpErrorRequest | <code>HttpInterceptorRequestError</code> | |
| controller | <code>IHttpInterceptController</code> | |
<b>Returns:</b>
`Promise<Request> | Request | void`
`MaybePromise<Partial<HttpFetchOptionsWithPath>> | void`

View file

@ -9,17 +9,17 @@ Define an interceptor to be executed after a response is received.
<b>Signature:</b>
```typescript
response?(httpResponse: IHttpResponse, controller: IHttpInterceptController): Promise<IHttpResponseInterceptorOverrides> | IHttpResponseInterceptorOverrides | void;
response?(httpResponse: HttpResponse, controller: IHttpInterceptController): MaybePromise<IHttpResponseInterceptorOverrides> | void;
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| httpResponse | <code>IHttpResponse</code> | |
| httpResponse | <code>HttpResponse</code> | |
| controller | <code>IHttpInterceptController</code> | |
<b>Returns:</b>
`Promise<IHttpResponseInterceptorOverrides> | IHttpResponseInterceptorOverrides | void`
`MaybePromise<IHttpResponseInterceptorOverrides> | void`

View file

@ -9,17 +9,17 @@ Define an interceptor to be executed if a response interceptor throws an error o
<b>Signature:</b>
```typescript
responseError?(httpErrorResponse: HttpErrorResponse, controller: IHttpInterceptController): Promise<IHttpResponseInterceptorOverrides> | IHttpResponseInterceptorOverrides | void;
responseError?(httpErrorResponse: HttpInterceptorResponseError, controller: IHttpInterceptController): MaybePromise<IHttpResponseInterceptorOverrides> | void;
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| httpErrorResponse | <code>HttpErrorResponse</code> | |
| httpErrorResponse | <code>HttpInterceptorResponseError</code> | |
| controller | <code>IHttpInterceptController</code> | |
<b>Returns:</b>
`Promise<IHttpResponseInterceptorOverrides> | IHttpResponseInterceptorOverrides | void`
`MaybePromise<IHttpResponseInterceptorOverrides> | void`

View file

@ -0,0 +1,11 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-public](./kibana-plugin-public.md) &gt; [HttpInterceptorRequestError](./kibana-plugin-public.httpinterceptorrequesterror.md) &gt; [error](./kibana-plugin-public.httpinterceptorrequesterror.error.md)
## HttpInterceptorRequestError.error property
<b>Signature:</b>
```typescript
error: Error;
```

View file

@ -0,0 +1,11 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-public](./kibana-plugin-public.md) &gt; [HttpInterceptorRequestError](./kibana-plugin-public.httpinterceptorrequesterror.md) &gt; [fetchOptions](./kibana-plugin-public.httpinterceptorrequesterror.fetchoptions.md)
## HttpInterceptorRequestError.fetchOptions property
<b>Signature:</b>
```typescript
fetchOptions: Readonly<HttpFetchOptionsWithPath>;
```

View file

@ -0,0 +1,20 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-public](./kibana-plugin-public.md) &gt; [HttpInterceptorRequestError](./kibana-plugin-public.httpinterceptorrequesterror.md)
## HttpInterceptorRequestError interface
<b>Signature:</b>
```typescript
export interface HttpInterceptorRequestError
```
## Properties
| Property | Type | Description |
| --- | --- | --- |
| [error](./kibana-plugin-public.httpinterceptorrequesterror.error.md) | <code>Error</code> | |
| [fetchOptions](./kibana-plugin-public.httpinterceptorrequesterror.fetchoptions.md) | <code>Readonly&lt;HttpFetchOptionsWithPath&gt;</code> | |

View file

@ -0,0 +1,11 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-public](./kibana-plugin-public.md) &gt; [HttpInterceptorResponseError](./kibana-plugin-public.httpinterceptorresponseerror.md) &gt; [error](./kibana-plugin-public.httpinterceptorresponseerror.error.md)
## HttpInterceptorResponseError.error property
<b>Signature:</b>
```typescript
error: Error | IHttpFetchError;
```

View file

@ -0,0 +1,20 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-public](./kibana-plugin-public.md) &gt; [HttpInterceptorResponseError](./kibana-plugin-public.httpinterceptorresponseerror.md)
## HttpInterceptorResponseError interface
<b>Signature:</b>
```typescript
export interface HttpInterceptorResponseError extends HttpResponse
```
## Properties
| Property | Type | Description |
| --- | --- | --- |
| [error](./kibana-plugin-public.httpinterceptorresponseerror.error.md) | <code>Error &#124; IHttpFetchError</code> | |
| [request](./kibana-plugin-public.httpinterceptorresponseerror.request.md) | <code>Readonly&lt;Request&gt;</code> | |

View file

@ -0,0 +1,11 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-public](./kibana-plugin-public.md) &gt; [HttpInterceptorResponseError](./kibana-plugin-public.httpinterceptorresponseerror.md) &gt; [request](./kibana-plugin-public.httpinterceptorresponseerror.request.md)
## HttpInterceptorResponseError.request property
<b>Signature:</b>
```typescript
request: Readonly<Request>;
```

View file

@ -1,8 +1,8 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-public](./kibana-plugin-public.md) &gt; [IHttpResponse](./kibana-plugin-public.ihttpresponse.md) &gt; [body](./kibana-plugin-public.ihttpresponse.body.md)
[Home](./index.md) &gt; [kibana-plugin-public](./kibana-plugin-public.md) &gt; [HttpResponse](./kibana-plugin-public.httpresponse.md) &gt; [body](./kibana-plugin-public.httpresponse.body.md)
## IHttpResponse.body property
## HttpResponse.body property
Parsed body received, may be undefined if there was an error.

View file

@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-public](./kibana-plugin-public.md) &gt; [HttpResponse](./kibana-plugin-public.httpresponse.md) &gt; [fetchOptions](./kibana-plugin-public.httpresponse.fetchoptions.md)
## HttpResponse.fetchOptions property
The original [HttpFetchOptionsWithPath](./kibana-plugin-public.httpfetchoptionswithpath.md) used to send this request.
<b>Signature:</b>
```typescript
readonly fetchOptions: Readonly<HttpFetchOptionsWithPath>;
```

View file

@ -0,0 +1,22 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-public](./kibana-plugin-public.md) &gt; [HttpResponse](./kibana-plugin-public.httpresponse.md)
## HttpResponse interface
<b>Signature:</b>
```typescript
export interface HttpResponse<TResponseBody = any>
```
## Properties
| Property | Type | Description |
| --- | --- | --- |
| [body](./kibana-plugin-public.httpresponse.body.md) | <code>TResponseBody</code> | Parsed body received, may be undefined if there was an error. |
| [fetchOptions](./kibana-plugin-public.httpresponse.fetchoptions.md) | <code>Readonly&lt;HttpFetchOptionsWithPath&gt;</code> | The original [HttpFetchOptionsWithPath](./kibana-plugin-public.httpfetchoptionswithpath.md) used to send this request. |
| [request](./kibana-plugin-public.httpresponse.request.md) | <code>Readonly&lt;Request&gt;</code> | Raw request sent to Kibana server. |
| [response](./kibana-plugin-public.httpresponse.response.md) | <code>Readonly&lt;Response&gt;</code> | Raw response received, may be undefined if there was an error. |

View file

@ -1,8 +1,8 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-public](./kibana-plugin-public.md) &gt; [IHttpResponse](./kibana-plugin-public.ihttpresponse.md) &gt; [request](./kibana-plugin-public.ihttpresponse.request.md)
[Home](./index.md) &gt; [kibana-plugin-public](./kibana-plugin-public.md) &gt; [HttpResponse](./kibana-plugin-public.httpresponse.md) &gt; [request](./kibana-plugin-public.httpresponse.request.md)
## IHttpResponse.request property
## HttpResponse.request property
Raw request sent to Kibana server.

View file

@ -1,8 +1,8 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-public](./kibana-plugin-public.md) &gt; [IHttpResponse](./kibana-plugin-public.ihttpresponse.md) &gt; [response](./kibana-plugin-public.ihttpresponse.response.md)
[Home](./index.md) &gt; [kibana-plugin-public](./kibana-plugin-public.md) &gt; [HttpResponse](./kibana-plugin-public.httpresponse.md) &gt; [response](./kibana-plugin-public.httpresponse.response.md)
## IHttpResponse.response property
## HttpResponse.response property
Raw response received, may be undefined if there was an error.

View file

@ -1,21 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-public](./kibana-plugin-public.md) &gt; [IHttpResponse](./kibana-plugin-public.ihttpresponse.md)
## IHttpResponse interface
<b>Signature:</b>
```typescript
export interface IHttpResponse<TResponseBody = any>
```
## Properties
| Property | Type | Description |
| --- | --- | --- |
| [body](./kibana-plugin-public.ihttpresponse.body.md) | <code>TResponseBody</code> | Parsed body received, may be undefined if there was an error. |
| [request](./kibana-plugin-public.ihttpresponse.request.md) | <code>Readonly&lt;Request&gt;</code> | Raw request sent to Kibana server. |
| [response](./kibana-plugin-public.ihttpresponse.response.md) | <code>Readonly&lt;Response&gt;</code> | Raw response received, may be undefined if there was an error. |

View file

@ -59,14 +59,16 @@ The plugin integrates with the core system via lifecycle events: `setup`<!-- -->
| [ErrorToastOptions](./kibana-plugin-public.errortoastoptions.md) | Options available for [IToasts](./kibana-plugin-public.itoasts.md) APIs. |
| [FatalErrorInfo](./kibana-plugin-public.fatalerrorinfo.md) | Represents the <code>message</code> and <code>stack</code> of a fatal Error |
| [FatalErrorsSetup](./kibana-plugin-public.fatalerrorssetup.md) | FatalErrors stop the Kibana Public Core and displays a fatal error screen with details about the Kibana build and the error. |
| [HttpErrorRequest](./kibana-plugin-public.httperrorrequest.md) | |
| [HttpErrorResponse](./kibana-plugin-public.httperrorresponse.md) | |
| [HttpFetchOptions](./kibana-plugin-public.httpfetchoptions.md) | All options that may be used with a [HttpHandler](./kibana-plugin-public.httphandler.md)<!-- -->. |
| [HttpFetchOptionsWithPath](./kibana-plugin-public.httpfetchoptionswithpath.md) | Similar to [HttpFetchOptions](./kibana-plugin-public.httpfetchoptions.md) but with the URL path included. |
| [HttpFetchQuery](./kibana-plugin-public.httpfetchquery.md) | |
| [HttpHandler](./kibana-plugin-public.httphandler.md) | A function for making an HTTP requests to Kibana's backend. See [HttpFetchOptions](./kibana-plugin-public.httpfetchoptions.md) for options and [IHttpResponse](./kibana-plugin-public.ihttpresponse.md) for the response. |
| [HttpHeadersInit](./kibana-plugin-public.httpheadersinit.md) | |
| [HttpHandler](./kibana-plugin-public.httphandler.md) | A function for making an HTTP requests to Kibana's backend. See [HttpFetchOptions](./kibana-plugin-public.httpfetchoptions.md) for options and [HttpResponse](./kibana-plugin-public.httpresponse.md) for the response. |
| [HttpHeadersInit](./kibana-plugin-public.httpheadersinit.md) | Headers to append to the request. Any headers that begin with <code>kbn-</code> are considered private to Core and will cause [HttpHandler](./kibana-plugin-public.httphandler.md) to throw an error. |
| [HttpInterceptor](./kibana-plugin-public.httpinterceptor.md) | An object that may define global interceptor functions for different parts of the request and response lifecycle. See [IHttpInterceptController](./kibana-plugin-public.ihttpinterceptcontroller.md)<!-- -->. |
| [HttpInterceptorRequestError](./kibana-plugin-public.httpinterceptorrequesterror.md) | |
| [HttpInterceptorResponseError](./kibana-plugin-public.httpinterceptorresponseerror.md) | |
| [HttpRequestInit](./kibana-plugin-public.httprequestinit.md) | Fetch API options available to [HttpHandler](./kibana-plugin-public.httphandler.md)<!-- -->s. |
| [HttpResponse](./kibana-plugin-public.httpresponse.md) | |
| [HttpSetup](./kibana-plugin-public.httpsetup.md) | |
| [I18nStart](./kibana-plugin-public.i18nstart.md) | I18nStart.Context is required by any localizable React component from @<!-- -->kbn/i18n and @<!-- -->elastic/eui packages and is supposed to be used as the topmost component for any i18n-compatible React tree. |
| [IAnonymousPaths](./kibana-plugin-public.ianonymouspaths.md) | APIs for denoting paths as not requiring authentication |
@ -74,7 +76,6 @@ The plugin integrates with the core system via lifecycle events: `setup`<!-- -->
| [IContextContainer](./kibana-plugin-public.icontextcontainer.md) | An object that handles registration of context providers and configuring handlers with context. |
| [IHttpFetchError](./kibana-plugin-public.ihttpfetcherror.md) | |
| [IHttpInterceptController](./kibana-plugin-public.ihttpinterceptcontroller.md) | Used to halt a request Promise chain in a [HttpInterceptor](./kibana-plugin-public.httpinterceptor.md)<!-- -->. |
| [IHttpResponse](./kibana-plugin-public.ihttpresponse.md) | |
| [IHttpResponseInterceptorOverrides](./kibana-plugin-public.ihttpresponseinterceptoroverrides.md) | Properties that can be returned by HttpInterceptor.request to override the response. |
| [ImageValidation](./kibana-plugin-public.imagevalidation.md) | |
| [IUiSettingsClient](./kibana-plugin-public.iuisettingsclient.md) | Client-side client that provides access to the advanced settings stored in elasticsearch. The settings provide control over the behavior of the Kibana application. For example, a user can specify how to display numeric or date fields. Users can adjust the settings via Management UI. [IUiSettingsClient](./kibana-plugin-public.iuisettingsclient.md) |

View file

@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-server](./kibana-plugin-server.md) &gt; [KibanaRequest](./kibana-plugin-server.kibanarequest.md) &gt; [isSystemRequest](./kibana-plugin-server.kibanarequest.issystemrequest.md)
## KibanaRequest.isSystemRequest property
Whether or not the request is a "system request" rather than an application-level request. Can be set on the client using the `HttpFetchOptions#asSystemRequest` option.
<b>Signature:</b>
```typescript
readonly isSystemRequest: boolean;
```

View file

@ -25,6 +25,7 @@ export declare class KibanaRequest<Params = unknown, Query = unknown, Body = unk
| [body](./kibana-plugin-server.kibanarequest.body.md) | | <code>Body</code> | |
| [events](./kibana-plugin-server.kibanarequest.events.md) | | <code>KibanaRequestEvents</code> | Request events [KibanaRequestEvents](./kibana-plugin-server.kibanarequestevents.md) |
| [headers](./kibana-plugin-server.kibanarequest.headers.md) | | <code>Headers</code> | Readonly copy of incoming request headers. |
| [isSystemRequest](./kibana-plugin-server.kibanarequest.issystemrequest.md) | | <code>boolean</code> | Whether or not the request is a "system request" rather than an application-level request. Can be set on the client using the <code>HttpFetchOptions#asSystemRequest</code> option. |
| [params](./kibana-plugin-server.kibanarequest.params.md) | | <code>Params</code> | |
| [query](./kibana-plugin-server.kibanarequest.query.md) | | <code>Query</code> | |
| [route](./kibana-plugin-server.kibanarequest.route.md) | | <code>RecursiveReadonly&lt;KibanaRequestRoute&lt;Method&gt;&gt;</code> | matched route details |

View file

@ -21,7 +21,17 @@ import { PromiseType } from 'utility-types';
export { $Values, Required, Optional, Class } from 'utility-types';
/**
* Returns wrapped type of a promise.
* A type that may or may not be a `Promise`.
*/
export type MaybePromise<T> = T | Promise<T>;
/**
* Converts a type to a `Promise`, unless it is already a `Promise`. Useful when proxying the return value of a possibly async function.
*/
export type ShallowPromise<T> = T extends Promise<infer U> ? Promise<U> : Promise<T>;
/**
* Returns wrapped type of a `Promise`.
*/
export type UnwrapPromise<T extends Promise<any>> = PromiseType<T>;
@ -39,11 +49,6 @@ export type UnwrapObservable<T extends ObservableLike<any>> = T extends Observab
? U
: never;
/**
* Converts a type to a `Promise`, unless it is already a `Promise`. Useful when proxying the return value of a possibly async function.
*/
export type ShallowPromise<T> = T extends Promise<infer U> ? Promise<U> : Promise<T>;
/**
* Ensures T is of type X.
*/

View file

@ -24,7 +24,7 @@ import { join } from 'path';
import { Fetch } from './fetch';
import { BasePath } from './base_path';
import { IHttpResponse } from './types';
import { HttpResponse, HttpFetchOptionsWithPath } from './types';
function delay<T>(duration: number) {
return new Promise<T>(r => setTimeout(r, duration));
@ -40,6 +40,19 @@ describe('Fetch', () => {
});
describe('http requests', () => {
it('should fail with invalid arguments', async () => {
fetchMock.get('*', {});
await expect(
fetchInstance.fetch(
// @ts-ignore
{ path: '/', headers: { hello: 'world' } },
{ headers: { hello: 'mars' } }
)
).rejects.toThrowErrorMatchingInlineSnapshot(
`"Invalid fetch arguments, must either be (string, object) or (object, undefined), received (object, object)"`
);
});
it('should use supplied request method', async () => {
fetchMock.post('*', {});
await fetchInstance.fetch('/my/path', { method: 'POST' });
@ -56,6 +69,15 @@ describe('Fetch', () => {
});
});
it('should not set Content-Type if undefined', async () => {
fetchMock.get('*', {});
await fetchInstance.fetch('/my/path', { headers: { 'Content-Type': undefined } });
expect(fetchMock.lastOptions()!.headers).toMatchObject({
'kbn-version': 'VERSION',
});
});
it('should use supplied pathname and querystring', async () => {
fetchMock.get('*', {});
await fetchInstance.fetch('/my/path', { query: { a: 'b' } });
@ -69,13 +91,106 @@ describe('Fetch', () => {
headers: { myHeader: 'foo' },
});
expect(fetchMock.lastOptions()!.headers).toEqual({
expect(fetchMock.lastOptions()!.headers).toMatchObject({
'content-type': 'application/json',
'kbn-version': 'VERSION',
myheader: 'foo',
});
});
it('should not allow overwriting of kbn-version header', async () => {
fetchMock.get('*', {});
await expect(
fetchInstance.fetch('/my/path', {
headers: { myHeader: 'foo', 'kbn-version': 'CUSTOM!' },
})
).rejects.toThrowErrorMatchingInlineSnapshot(
`"Invalid fetch headers, headers beginning with \\"kbn-\\" are not allowed: [kbn-version]"`
);
});
it('should not set kbn-system-request header by default', async () => {
fetchMock.get('*', {});
await fetchInstance.fetch('/my/path', {
headers: { myHeader: 'foo' },
});
expect(fetchMock.lastOptions()!.headers['kbn-system-request']).toBeUndefined();
});
it('should not set kbn-system-request header when asSystemRequest: false', async () => {
fetchMock.get('*', {});
await fetchInstance.fetch('/my/path', {
headers: { myHeader: 'foo' },
asSystemRequest: false,
});
expect(fetchMock.lastOptions()!.headers['kbn-system-request']).toBeUndefined();
});
it('should set kbn-system-request header when asSystemRequest: true', async () => {
fetchMock.get('*', {});
await fetchInstance.fetch('/my/path', {
headers: { myHeader: 'foo' },
asSystemRequest: true,
});
expect(fetchMock.lastOptions()!.headers).toMatchObject({
'kbn-system-request': 'true',
myheader: 'foo',
});
});
it('should not allow overwriting of kbn-system-request when asSystemRequest: true', async () => {
fetchMock.get('*', {});
await expect(
fetchInstance.fetch('/my/path', {
headers: { myHeader: 'foo', 'kbn-system-request': 'ANOTHER!' },
asSystemRequest: true,
})
).rejects.toThrowErrorMatchingInlineSnapshot(
`"Invalid fetch headers, headers beginning with \\"kbn-\\" are not allowed: [kbn-system-request]"`
);
});
it('should not allow overwriting of kbn-system-request when asSystemRequest: false', async () => {
fetchMock.get('*', {});
await expect(
fetchInstance.fetch('/my/path', {
headers: { myHeader: 'foo', 'kbn-system-request': 'ANOTHER!' },
asSystemRequest: false,
})
).rejects.toThrowErrorMatchingInlineSnapshot(
`"Invalid fetch headers, headers beginning with \\"kbn-\\" are not allowed: [kbn-system-request]"`
);
});
// Deprecated header used by legacy platform pre-7.7. Remove in 8.x.
it('should not allow overwriting of kbn-system-api when asSystemRequest: true', async () => {
fetchMock.get('*', {});
await expect(
fetchInstance.fetch('/my/path', {
headers: { myHeader: 'foo', 'kbn-system-api': 'ANOTHER!' },
asSystemRequest: true,
})
).rejects.toThrowErrorMatchingInlineSnapshot(
`"Invalid fetch headers, headers beginning with \\"kbn-\\" are not allowed: [kbn-system-api]"`
);
});
// Deprecated header used by legacy platform pre-7.7. Remove in 8.x.
it('should not allow overwriting of kbn-system-api when asSystemRequest: false', async () => {
fetchMock.get('*', {});
await expect(
fetchInstance.fetch('/my/path', {
headers: { myHeader: 'foo', 'kbn-system-api': 'ANOTHER!' },
asSystemRequest: false,
})
).rejects.toThrowErrorMatchingInlineSnapshot(
`"Invalid fetch headers, headers beginning with \\"kbn-\\" are not allowed: [kbn-system-api]"`
);
});
it('should return response', async () => {
fetchMock.get('*', { foo: 'bar' });
const json = await fetchInstance.fetch('/my/path');
@ -121,11 +236,35 @@ describe('Fetch', () => {
const response = await fetchInstance.fetch('/my/path', { asResponse: true });
expect(response.fetchOptions).toMatchObject({
path: '/my/path',
asResponse: true,
});
expect(response.request).toBeInstanceOf(Request);
expect(response.response).toBeInstanceOf(Response);
expect(response.body).toEqual({ foo: 'bar' });
});
it('should expose asSystemRequest: true on detailed response object when asResponse = true', async () => {
fetchMock.get('*', { foo: 'bar' });
const response = await fetchInstance.fetch('/my/path', {
asResponse: true,
asSystemRequest: true,
});
expect(response.fetchOptions.asSystemRequest).toBe(true);
});
it('should expose asSystemRequest: false on detailed response object when asResponse = true', async () => {
fetchMock.get('*', { foo: 'bar' });
const response = await fetchInstance.fetch('/my/path', {
asResponse: true,
asSystemRequest: false,
});
expect(response.fetchOptions.asSystemRequest).toBe(false);
});
it('should reject on network error', async () => {
expect.assertions(1);
fetchMock.get('*', { status: 500 });
@ -245,13 +384,18 @@ describe('Fetch', () => {
it('should be able to manipulate request instance', async () => {
fetchInstance.intercept({
request(request) {
request.headers.set('Content-Type', 'CustomContentType');
request(options) {
return {
headers: {
...options.headers,
'Content-Type': 'CustomContentType',
},
};
},
});
fetchInstance.intercept({
request(request) {
return new Request('/my/route', request);
request() {
return { path: '/my/route' };
},
});
@ -262,7 +406,7 @@ describe('Fetch', () => {
expect(fetchMock.lastOptions()!.headers).toMatchObject({
'content-type': 'CustomContentType',
});
expect(fetchMock.lastUrl()).toBe('/my/route');
expect(fetchMock.lastUrl()).toBe('http://localhost/myBase/my/route');
});
it('should call interceptors in correct order', async () => {
@ -402,8 +546,8 @@ describe('Fetch', () => {
fetchInstance.intercept({
request: unusedSpy,
requestError({ request }) {
return new Request('/my/route', request);
requestError() {
return { path: '/my/route' };
},
response: usedSpy,
});
@ -423,16 +567,16 @@ describe('Fetch', () => {
it('should accumulate request information', async () => {
const routes = ['alpha', 'beta', 'gamma'];
const createRequest = jest.fn(
(request: Request) => new Request(`/api/${routes.shift()}`, request)
);
const createRequest = jest.fn((options: HttpFetchOptionsWithPath) => ({
path: `/api/${routes.shift()}`,
}));
fetchInstance.intercept({
request: createRequest,
});
fetchInstance.intercept({
requestError(httpErrorRequest) {
return httpErrorRequest.request;
return httpErrorRequest.fetchOptions;
},
});
fetchInstance.intercept({
@ -450,15 +594,15 @@ describe('Fetch', () => {
await expect(fetchInstance.fetch('/my/route')).resolves.toEqual({ foo: 'bar' });
expect(fetchMock.called()).toBe(true);
expect(routes.length).toBe(0);
expect(createRequest.mock.calls[0][0].url).toContain('/my/route');
expect(createRequest.mock.calls[1][0].url).toContain('/api/alpha');
expect(createRequest.mock.calls[2][0].url).toContain('/api/beta');
expect(createRequest.mock.calls[0][0].path).toContain('/my/route');
expect(createRequest.mock.calls[1][0].path).toContain('/api/alpha');
expect(createRequest.mock.calls[2][0].path).toContain('/api/beta');
expect(fetchMock.lastCall()!.request.url).toContain('/api/gamma');
});
it('should accumulate response information', async () => {
const bodies = ['alpha', 'beta', 'gamma'];
const createResponse = jest.fn((httpResponse: IHttpResponse) => ({
const createResponse = jest.fn((httpResponse: HttpResponse) => ({
body: bodies.shift(),
}));
@ -550,7 +694,7 @@ describe('Fetch', () => {
fetchInstance.intercept({
requestError(httpErrorRequest) {
return httpErrorRequest.request;
return httpErrorRequest.fetchOptions;
},
response: usedSpy,
});

View file

@ -20,10 +20,16 @@
import { merge } from 'lodash';
import { format } from 'url';
import { IBasePath, HttpInterceptor, HttpHandler, HttpFetchOptions, IHttpResponse } from './types';
import {
IBasePath,
HttpInterceptor,
HttpHandler,
HttpFetchOptions,
HttpResponse,
HttpFetchOptionsWithPath,
} from './types';
import { HttpFetchError } from './http_fetch_error';
import { HttpInterceptController } from './http_intercept_controller';
import { HttpResponse } from './response';
import { interceptRequest, interceptResponse } from './intercept';
import { HttpInterceptHaltError } from './http_intercept_halt_error';
@ -60,29 +66,30 @@ export class Fetch {
public readonly put = this.shorthand('PUT');
public fetch: HttpHandler = async <TResponseBody>(
path: string,
options: HttpFetchOptions = {}
pathOrOptions: string | HttpFetchOptionsWithPath,
options?: HttpFetchOptions
) => {
const initialRequest = this.createRequest(path, options);
const optionsWithPath = validateFetchArguments(pathOrOptions, options);
const controller = new HttpInterceptController();
// We wrap the interception in a separate promise to ensure that when
// a halt is called we do not resolve or reject, halting handling of the promise.
return new Promise<TResponseBody | IHttpResponse<TResponseBody>>(async (resolve, reject) => {
return new Promise<TResponseBody | HttpResponse<TResponseBody>>(async (resolve, reject) => {
try {
const interceptedRequest = await interceptRequest(
initialRequest,
const interceptedOptions = await interceptRequest(
optionsWithPath,
this.interceptors,
controller
);
const initialResponse = this.fetchResponse(interceptedRequest);
const initialResponse = this.fetchResponse(interceptedOptions);
const interceptedResponse = await interceptResponse(
interceptedOptions,
initialResponse,
this.interceptors,
controller
);
if (options.asResponse) {
if (optionsWithPath.asResponse) {
resolve(interceptedResponse);
} else {
resolve(interceptedResponse.body);
@ -95,38 +102,44 @@ export class Fetch {
});
};
private createRequest(path: string, options?: HttpFetchOptions): Request {
private createRequest(options: HttpFetchOptionsWithPath): Request {
// Merge and destructure options out that are not applicable to the Fetch API.
const { query, prependBasePath: shouldPrependBasePath, asResponse, ...fetchOptions } = merge(
const {
query,
prependBasePath: shouldPrependBasePath,
asResponse,
asSystemRequest,
...fetchOptions
} = merge(
{
method: 'GET',
credentials: 'same-origin',
prependBasePath: true,
headers: {
'kbn-version': this.params.kibanaVersion,
'Content-Type': 'application/json',
},
},
options || {}
options,
{
headers: {
'Content-Type': 'application/json',
...options.headers,
'kbn-version': this.params.kibanaVersion,
},
}
);
const url = format({
pathname: shouldPrependBasePath ? this.params.basePath.prepend(path) : path,
pathname: shouldPrependBasePath ? this.params.basePath.prepend(options.path) : options.path,
query,
});
if (
options &&
options.headers &&
'Content-Type' in options.headers &&
options.headers['Content-Type'] === undefined
) {
delete fetchOptions.headers['Content-Type'];
// Make sure the system request header is only present if `asSystemRequest` is true.
if (asSystemRequest) {
fetchOptions.headers['kbn-system-request'] = 'true';
}
return new Request(url, fetchOptions);
}
private async fetchResponse(request: Request) {
private async fetchResponse(fetchOptions: HttpFetchOptionsWithPath): Promise<HttpResponse<any>> {
const request = this.createRequest(fetchOptions);
let response: Response;
let body = null;
@ -164,11 +177,46 @@ export class Fetch {
throw new HttpFetchError(response.statusText, request, response, body);
}
return new HttpResponse({ request, response, body });
return { fetchOptions, request, response, body };
}
private shorthand(method: string) {
return (path: string, options: HttpFetchOptions = {}) =>
this.fetch(path, { ...options, method });
private shorthand(method: string): HttpHandler {
return (pathOrOptions: string | HttpFetchOptionsWithPath, options?: HttpFetchOptions) => {
const optionsWithPath = validateFetchArguments(pathOrOptions, options);
return this.fetch({ ...optionsWithPath, method });
};
}
}
/**
* Ensure that the overloaded arguments to `HttpHandler` are valid.
*/
const validateFetchArguments = (
pathOrOptions: string | HttpFetchOptionsWithPath,
options?: HttpFetchOptions
): HttpFetchOptionsWithPath => {
let fullOptions: HttpFetchOptionsWithPath;
if (typeof pathOrOptions === 'string' && (typeof options === 'object' || options === undefined)) {
fullOptions = { ...options, path: pathOrOptions };
} else if (typeof pathOrOptions === 'object' && options === undefined) {
fullOptions = pathOrOptions;
} else {
throw new Error(
`Invalid fetch arguments, must either be (string, object) or (object, undefined), received (${typeof pathOrOptions}, ${typeof options})`
);
}
const invalidHeaders = Object.keys(fullOptions.headers ?? {}).filter(headerName =>
headerName.startsWith('kbn-')
);
if (invalidHeaders.length) {
throw new Error(
`Invalid fetch headers, headers beginning with "kbn-" are not allowed: [${invalidHeaders.join(
','
)}]`
);
}
return fullOptions;
};

View file

@ -19,28 +19,31 @@
import { HttpInterceptController } from './http_intercept_controller';
import { HttpInterceptHaltError } from './http_intercept_halt_error';
import { HttpInterceptor, IHttpResponse } from './types';
import { HttpResponse } from './response';
import { HttpInterceptor, HttpResponse, HttpFetchOptionsWithPath } from './types';
export async function interceptRequest(
request: Request,
options: HttpFetchOptionsWithPath,
interceptors: ReadonlySet<HttpInterceptor>,
controller: HttpInterceptController
): Promise<Request> {
let next = request;
): Promise<HttpFetchOptionsWithPath> {
let current: HttpFetchOptionsWithPath;
return [...interceptors].reduceRight(
(promise, interceptor) =>
promise.then(
async (current: Request) => {
next = current;
async fetchOptions => {
current = fetchOptions;
checkHalt(controller);
if (!interceptor.request) {
return current;
return fetchOptions;
}
return (await interceptor.request(current, controller)) || current;
const overrides = await interceptor.request(current, controller);
return {
...current,
...overrides,
};
},
async error => {
checkHalt(controller, error);
@ -49,26 +52,33 @@ export async function interceptRequest(
throw error;
}
const nextRequest = await interceptor.requestError({ error, request: next }, controller);
const overrides = await interceptor.requestError(
{ error, fetchOptions: current },
controller
);
if (!nextRequest) {
if (!overrides) {
throw error;
}
next = nextRequest;
return next;
current = {
...current,
...overrides,
};
return current;
}
),
Promise.resolve(request)
Promise.resolve(options)
);
}
export async function interceptResponse(
responsePromise: Promise<IHttpResponse>,
fetchOptions: HttpFetchOptionsWithPath,
responsePromise: Promise<HttpResponse>,
interceptors: ReadonlySet<HttpInterceptor>,
controller: HttpInterceptController
): Promise<IHttpResponse> {
let current: IHttpResponse;
): Promise<HttpResponse> {
let current: HttpResponse;
return await [...interceptors].reduce(
(promise, interceptor) =>
@ -83,10 +93,10 @@ export async function interceptResponse(
const interceptorOverrides = (await interceptor.response(httpResponse, controller)) || {};
return new HttpResponse({
return {
...httpResponse,
...interceptorOverrides,
});
};
},
async error => {
const request = error.request || (current && current.request);
@ -101,6 +111,7 @@ export async function interceptResponse(
const next = await interceptor.responseError(
{
error,
fetchOptions,
request,
response: error.response || (current && current.response),
body: error.body || (current && current.body),
@ -114,7 +125,7 @@ export async function interceptResponse(
throw error;
}
return new HttpResponse({ ...next, request });
return { ...next, request, fetchOptions };
} catch (err) {
checkHalt(controller, err);
throw err;

View file

@ -1,40 +0,0 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { IHttpResponse } from './types';
export class HttpResponse<TResponseBody = any> implements IHttpResponse<TResponseBody> {
public readonly request: Request;
public readonly response?: Response;
public readonly body?: TResponseBody;
constructor({
request,
response,
body,
}: {
request: Request;
response?: Response;
body?: TResponseBody;
}) {
this.request = request;
this.response = response;
this.body = body;
}
}

View file

@ -18,6 +18,7 @@
*/
import { Observable } from 'rxjs';
import { MaybePromise } from '@kbn/utility-types';
/** @public */
export interface HttpSetup {
@ -110,7 +111,11 @@ export interface IAnonymousPaths {
register(path: string): void;
}
/** @public */
/**
* Headers to append to the request. Any headers that begin with `kbn-` are considered private to Core and will cause
* {@link HttpHandler} to throw an error.
* @public
*/
export interface HttpHeadersInit {
[name: string]: any;
}
@ -217,30 +222,54 @@ export interface HttpFetchOptions extends HttpRequestInit {
headers?: HttpHeadersInit;
/**
* When `true` the return type of {@link HttpHandler} will be an {@link IHttpResponse} with detailed request and
* Whether or not the request should include the "system request" header to differentiate an end user request from
* Kibana internal request.
* Can be read on the server-side using KibanaRequest#isSystemRequest. Defaults to `false`.
*/
asSystemRequest?: boolean;
/**
* When `true` the return type of {@link HttpHandler} will be an {@link HttpResponse} with detailed request and
* response information. When `false`, the return type will just be the parsed response body. Defaults to `false`.
*/
asResponse?: boolean;
}
/**
* Similar to {@link HttpFetchOptions} but with the URL path included.
* @public
*/
export interface HttpFetchOptionsWithPath extends HttpFetchOptions {
/*
* The path on the Kibana server to send the request to. Should not include the basePath.
*/
path: string;
}
/**
* A function for making an HTTP requests to Kibana's backend. See {@link HttpFetchOptions} for options and
* {@link IHttpResponse} for the response.
* {@link HttpResponse} for the response.
*
* @param path the path on the Kibana server to send the request to. Should not include the basePath.
* @param options {@link HttpFetchOptions}
* @returns a Promise that resolves to a {@link IHttpResponse}
* @returns a Promise that resolves to a {@link HttpResponse}
* @public
*/
export interface HttpHandler {
<TResponseBody = any>(path: string, options: HttpFetchOptions & { asResponse: true }): Promise<
IHttpResponse<TResponseBody>
HttpResponse<TResponseBody>
>;
<TResponseBody = any>(options: HttpFetchOptionsWithPath & { asResponse: true }): Promise<
HttpResponse<TResponseBody>
>;
<TResponseBody = any>(path: string, options?: HttpFetchOptions): Promise<TResponseBody>;
<TResponseBody = any>(options: HttpFetchOptionsWithPath): Promise<TResponseBody>;
}
/** @public */
export interface IHttpResponse<TResponseBody = any> {
export interface HttpResponse<TResponseBody = any> {
/** The original {@link HttpFetchOptionsWithPath} used to send this request. */
readonly fetchOptions: Readonly<HttpFetchOptionsWithPath>;
/** Raw request sent to Kibana server. */
readonly request: Readonly<Request>;
/** Raw response received, may be undefined if there was an error. */
@ -276,12 +305,13 @@ export interface IHttpFetchError extends Error {
}
/** @public */
export interface HttpErrorResponse extends IHttpResponse {
export interface HttpInterceptorResponseError extends HttpResponse {
request: Readonly<Request>;
error: Error | IHttpFetchError;
}
/** @public */
export interface HttpErrorRequest {
request: Request;
export interface HttpInterceptorRequestError {
fetchOptions: Readonly<HttpFetchOptionsWithPath>;
error: Error;
}
@ -298,39 +328,39 @@ export interface HttpInterceptor {
* @param controller {@link IHttpInterceptController}
*/
request?(
request: Request,
fetchOptions: Readonly<HttpFetchOptionsWithPath>,
controller: IHttpInterceptController
): Promise<Request> | Request | void;
): MaybePromise<Partial<HttpFetchOptionsWithPath>> | void;
/**
* Define an interceptor to be executed if a request interceptor throws an error or returns a rejected Promise.
* @param httpErrorRequest {@link HttpErrorRequest}
* @param httpErrorRequest {@link HttpInterceptorRequestError}
* @param controller {@link IHttpInterceptController}
*/
requestError?(
httpErrorRequest: HttpErrorRequest,
httpErrorRequest: HttpInterceptorRequestError,
controller: IHttpInterceptController
): Promise<Request> | Request | void;
): MaybePromise<Partial<HttpFetchOptionsWithPath>> | void;
/**
* Define an interceptor to be executed after a response is received.
* @param httpResponse {@link IHttpResponse}
* @param httpResponse {@link HttpResponse}
* @param controller {@link IHttpInterceptController}
*/
response?(
httpResponse: IHttpResponse,
httpResponse: HttpResponse,
controller: IHttpInterceptController
): Promise<IHttpResponseInterceptorOverrides> | IHttpResponseInterceptorOverrides | void;
): MaybePromise<IHttpResponseInterceptorOverrides> | void;
/**
* Define an interceptor to be executed if a response interceptor throws an error or returns a rejected Promise.
* @param httpErrorResponse {@link HttpErrorResponse}
* @param httpErrorResponse {@link HttpInterceptorResponseError}
* @param controller {@link IHttpInterceptController}
*/
responseError?(
httpErrorResponse: HttpErrorResponse,
httpErrorResponse: HttpInterceptorResponseError,
controller: IHttpInterceptController
): Promise<IHttpResponseInterceptorOverrides> | IHttpResponseInterceptorOverrides | void;
): MaybePromise<IHttpResponseInterceptorOverrides> | void;
}
/**

View file

@ -144,11 +144,12 @@ export {
HttpHeadersInit,
HttpRequestInit,
HttpFetchOptions,
HttpFetchOptionsWithPath,
HttpFetchQuery,
HttpErrorResponse,
HttpErrorRequest,
HttpInterceptorResponseError,
HttpInterceptorRequestError,
HttpInterceptor,
IHttpResponse,
HttpResponse,
HttpHandler,
IBasePath,
IAnonymousPaths,

View file

@ -9,6 +9,7 @@ import { EuiButtonEmptyProps } from '@elastic/eui';
import { EuiGlobalToastListToast } from '@elastic/eui';
import { ExclusiveUnion } from '@elastic/eui';
import { IconType } from '@elastic/eui';
import { MaybePromise } from '@kbn/utility-types';
import { Observable } from 'rxjs';
import React from 'react';
import * as Rx from 'rxjs';
@ -577,28 +578,21 @@ export type HandlerFunction<T extends object> = (context: T, ...args: any[]) =>
// @public
export type HandlerParameters<T extends HandlerFunction<any>> = T extends (context: any, ...args: infer U) => any ? U : never;
// @public (undocumented)
export interface HttpErrorRequest {
// (undocumented)
error: Error;
// (undocumented)
request: Request;
}
// @public (undocumented)
export interface HttpErrorResponse extends IHttpResponse {
// (undocumented)
error: Error | IHttpFetchError;
}
// @public
export interface HttpFetchOptions extends HttpRequestInit {
asResponse?: boolean;
asSystemRequest?: boolean;
headers?: HttpHeadersInit;
prependBasePath?: boolean;
query?: HttpFetchQuery;
}
// @public
export interface HttpFetchOptionsWithPath extends HttpFetchOptions {
// (undocumented)
path: string;
}
// @public (undocumented)
export interface HttpFetchQuery {
// (undocumented)
@ -610,12 +604,18 @@ export interface HttpHandler {
// (undocumented)
<TResponseBody = any>(path: string, options: HttpFetchOptions & {
asResponse: true;
}): Promise<IHttpResponse<TResponseBody>>;
}): Promise<HttpResponse<TResponseBody>>;
// (undocumented)
<TResponseBody = any>(options: HttpFetchOptionsWithPath & {
asResponse: true;
}): Promise<HttpResponse<TResponseBody>>;
// (undocumented)
<TResponseBody = any>(path: string, options?: HttpFetchOptions): Promise<TResponseBody>;
// (undocumented)
<TResponseBody = any>(options: HttpFetchOptionsWithPath): Promise<TResponseBody>;
}
// @public (undocumented)
// @public
export interface HttpHeadersInit {
// (undocumented)
[name: string]: any;
@ -623,10 +623,26 @@ export interface HttpHeadersInit {
// @public
export interface HttpInterceptor {
request?(request: Request, controller: IHttpInterceptController): Promise<Request> | Request | void;
requestError?(httpErrorRequest: HttpErrorRequest, controller: IHttpInterceptController): Promise<Request> | Request | void;
response?(httpResponse: IHttpResponse, controller: IHttpInterceptController): Promise<IHttpResponseInterceptorOverrides> | IHttpResponseInterceptorOverrides | void;
responseError?(httpErrorResponse: HttpErrorResponse, controller: IHttpInterceptController): Promise<IHttpResponseInterceptorOverrides> | IHttpResponseInterceptorOverrides | void;
request?(fetchOptions: Readonly<HttpFetchOptionsWithPath>, controller: IHttpInterceptController): MaybePromise<Partial<HttpFetchOptionsWithPath>> | void;
requestError?(httpErrorRequest: HttpInterceptorRequestError, controller: IHttpInterceptController): MaybePromise<Partial<HttpFetchOptionsWithPath>> | void;
response?(httpResponse: HttpResponse, controller: IHttpInterceptController): MaybePromise<IHttpResponseInterceptorOverrides> | void;
responseError?(httpErrorResponse: HttpInterceptorResponseError, controller: IHttpInterceptController): MaybePromise<IHttpResponseInterceptorOverrides> | void;
}
// @public (undocumented)
export interface HttpInterceptorRequestError {
// (undocumented)
error: Error;
// (undocumented)
fetchOptions: Readonly<HttpFetchOptionsWithPath>;
}
// @public (undocumented)
export interface HttpInterceptorResponseError extends HttpResponse {
// (undocumented)
error: Error | IHttpFetchError;
// (undocumented)
request: Readonly<Request>;
}
// @public
@ -647,6 +663,14 @@ export interface HttpRequestInit {
window?: null;
}
// @public (undocumented)
export interface HttpResponse<TResponseBody = any> {
readonly body?: TResponseBody;
readonly fetchOptions: Readonly<HttpFetchOptionsWithPath>;
readonly request: Readonly<Request>;
readonly response?: Readonly<Response>;
}
// @public (undocumented)
export interface HttpSetup {
addLoadingCountSource(countSource$: Observable<number>): void;
@ -718,13 +742,6 @@ export interface IHttpInterceptController {
halted: boolean;
}
// @public (undocumented)
export interface IHttpResponse<TResponseBody = any> {
readonly body?: TResponseBody;
readonly request: Readonly<Request>;
readonly response?: Readonly<Response>;
}
// @public
export interface IHttpResponseInterceptorOverrides<TResponseBody = any> {
readonly body?: TResponseBody;

View file

@ -66,6 +66,57 @@ describe('KibanaRequest', () => {
});
});
describe('isSytemApi property', () => {
it('is false when no kbn-system-request header is set', () => {
const request = httpServerMock.createRawRequest({
headers: { custom: 'one' },
});
const kibanaRequest = KibanaRequest.from(request);
expect(kibanaRequest.isSystemRequest).toBe(false);
});
it('is true when kbn-system-request header is set to true', () => {
const request = httpServerMock.createRawRequest({
headers: { custom: 'one', 'kbn-system-request': 'true' },
});
const kibanaRequest = KibanaRequest.from(request);
expect(kibanaRequest.isSystemRequest).toBe(true);
});
it('is false when kbn-system-request header is set to false', () => {
const request = httpServerMock.createRawRequest({
headers: { custom: 'one', 'kbn-system-request': 'false' },
});
const kibanaRequest = KibanaRequest.from(request);
expect(kibanaRequest.isSystemRequest).toBe(false);
});
// Remove support for kbn-system-api header in 8.x. Only used by legacy platform.
it('is false when no kbn-system-api header is set', () => {
const request = httpServerMock.createRawRequest({
headers: { custom: 'one' },
});
const kibanaRequest = KibanaRequest.from(request);
expect(kibanaRequest.isSystemRequest).toBe(false);
});
it('is true when kbn-system-api header is set to true', () => {
const request = httpServerMock.createRawRequest({
headers: { custom: 'one', 'kbn-system-api': 'true' },
});
const kibanaRequest = KibanaRequest.from(request);
expect(kibanaRequest.isSystemRequest).toBe(true);
});
it('is false when kbn-system-api header is set to false', () => {
const request = httpServerMock.createRawRequest({
headers: { custom: 'one', 'kbn-system-api': 'false' },
});
const kibanaRequest = KibanaRequest.from(request);
expect(kibanaRequest.isSystemRequest).toBe(false);
});
});
describe('RouteSchema type inferring', () => {
it('should work with config-schema', () => {
const body = Buffer.from('body!');

View file

@ -127,6 +127,11 @@ export class KibanaRequest<
* This property will contain a `filtered` copy of request headers.
*/
public readonly headers: Headers;
/**
* Whether or not the request is a "system request" rather than an application-level request.
* Can be set on the client using the `HttpFetchOptions#asSystemRequest` option.
*/
public readonly isSystemRequest: boolean;
/** {@link IKibanaSocket} */
public readonly socket: IKibanaSocket;
@ -147,6 +152,10 @@ export class KibanaRequest<
) {
this.url = request.url;
this.headers = deepFreeze({ ...request.headers });
this.isSystemRequest =
request.headers['kbn-system-request'] === 'true' ||
// Remove support for `kbn-system-api` in 8.x. Used only by legacy platform.
request.headers['kbn-system-api'] === 'true';
// prevent Symbol exposure via Object.getOwnPropertySymbols()
Object.defineProperty(this, requestSymbol, {

View file

@ -888,6 +888,7 @@ export class KibanaRequest<Params = unknown, Query = unknown, Body = unknown, Me
// @internal
static from<P, Q, B>(req: Request, routeSchemas?: RouteValidator<P, Q, B> | RouteValidatorFullConfig<P, Q, B>, withoutSecretHeaders?: boolean): KibanaRequest<P, Q, B, any>;
readonly headers: Headers;
readonly isSystemRequest: boolean;
// (undocumented)
readonly params: Params;
// (undocumented)

View file

@ -24,6 +24,7 @@ const SYSTEM_API_HEADER_NAME = 'kbn-system-api';
*
* @param request HAPI request object
* @return true if request is a system API request; false, otherwise
* @deprecated Use KibanaRequest#isSystemApi
*/
export function isSystemApiRequest(request) {
return !!request.headers[SYSTEM_API_HEADER_NAME];

View file

@ -32,6 +32,7 @@ export interface KFetchQuery {
export interface KFetchOptions extends HttpRequestInit {
pathname: string;
query?: KFetchQuery;
asSystemRequest?: boolean;
}
export interface KFetchKibanaOptions {

View file

@ -44,10 +44,8 @@ describe('Sync search strategy', () => {
},
{}
);
expect(mockCoreSetup.http.fetch.mock.calls[0][0]).toBe(
`/internal/search/${SYNC_SEARCH_STRATEGY}`
);
expect(mockCoreSetup.http.fetch.mock.calls[0][1]).toEqual({
expect(mockCoreSetup.http.fetch.mock.calls[0][0]).toEqual({
path: `/internal/search/${SYNC_SEARCH_STRATEGY}`,
body: JSON.stringify({
serverStrategy: 'SYNC_SEARCH_STRATEGY',
}),

View file

@ -36,14 +36,12 @@ export const syncSearchStrategyProvider: TSearchStrategyProvider<typeof SYNC_SEA
request: ISyncSearchRequest,
options: ISearchOptions = {}
) => {
const response: Promise<IKibanaSearchResponse> = context.core.http.fetch(
`/internal/search/${request.serverStrategy}`,
{
method: 'POST',
body: JSON.stringify(request),
signal: options.signal,
}
);
const response: Promise<IKibanaSearchResponse> = context.core.http.fetch({
path: `/internal/search/${request.serverStrategy}`,
method: 'POST',
body: JSON.stringify(request),
signal: options.signal,
});
return from(response);
};

View file

@ -17,7 +17,7 @@
* under the License.
*/
import { CoreSetup, Plugin, PluginInitializerContext } from 'kibana/public';
import { CoreSetup, CoreStart, Plugin, PluginInitializerContext } from 'kibana/public';
import { CorePluginAPluginSetup } from '../../core_plugin_a/public/plugin';
declare global {
@ -52,7 +52,17 @@ export class CorePluginBPlugin
};
}
public start() {}
public async start(core: CoreStart, deps: {}) {
return {
sendSystemRequest: async (asSystemRequest: boolean) => {
const response = await core.http.post<string>('/core_plugin_b/system_request', {
asSystemRequest,
});
return `/core_plugin_b/system_request says: "${response}"`;
},
};
}
public stop() {}
}

View file

@ -54,6 +54,16 @@ export class CorePluginBPlugin implements Plugin {
return res.ok({ body: `ID: ${req.query.id} - ${req.body.bar.toUpperCase()}` });
}
);
router.post(
{
path: '/core_plugin_b/system_request',
validate: false,
},
async (context, req, res) => {
return res.ok({ body: `System request? ${req.isSystemRequest}` });
}
);
}
public start() {}

View file

@ -54,5 +54,15 @@ export default function({ getService }: PluginFunctionalProviderContext) {
statusCode: 400,
});
});
it('sets request.isSystemRequest when kbn-system-request header is set', async () => {
await supertest
.post('/core_plugin_b/system_request')
.set('kbn-xsrf', 'anything')
.set('kbn-system-request', 'true')
.send()
.expect(200)
.expect('System request? true');
});
});
}

View file

@ -64,7 +64,7 @@ export default function({ getService, getPageObjects }: PluginFunctionalProvider
});
});
describe('have env data provided', function describeIndexTests() {
describe('have env data provided', () => {
before(async () => {
await PageObjects.common.navigateToApp('bar');
});
@ -75,5 +75,27 @@ export default function({ getService, getPageObjects }: PluginFunctionalProvider
expect(envData.packageInfo.version).to.be.a('string');
});
});
describe('http fetching', () => {
before(async () => {
await PageObjects.common.navigateToApp('settings');
});
it('should send kbn-system-request header when asSystemRequest: true', async () => {
expect(
await browser.executeAsync(async cb => {
window.__coreProvider.start.plugins.core_plugin_b.sendSystemRequest(true).then(cb);
})
).to.be('/core_plugin_b/system_request says: "System request? true"');
});
it('should not send kbn-system-request header when asSystemRequest: false', async () => {
expect(
await browser.executeAsync(async cb => {
window.__coreProvider.start.plugins.core_plugin_b.sendSystemRequest(false).then(cb);
})
).to.be('/core_plugin_b/system_request says: "System request? false"');
});
});
});
}

View file

@ -278,8 +278,8 @@ describe('IndexPattern Data Panel', () => {
function testProps() {
const setState = jest.fn();
core.http.get.mockImplementation(async (url: string) => {
const parts = url.split('/');
core.http.get.mockImplementation(async ({ path }) => {
const parts = path.split('/');
const indexPatternTitle = parts[parts.length - 1];
return {
indexPatternTitle: `${indexPatternTitle}_testtitle`,
@ -397,7 +397,8 @@ describe('IndexPattern Data Panel', () => {
expect(setState).toHaveBeenCalledTimes(2);
expect(core.http.get).toHaveBeenCalledTimes(2);
expect(core.http.get).toHaveBeenCalledWith('/api/lens/existing_fields/a', {
expect(core.http.get).toHaveBeenCalledWith({
path: '/api/lens/existing_fields/a',
query: {
fromDate: '2019-01-01',
toDate: '2020-01-01',
@ -405,7 +406,8 @@ describe('IndexPattern Data Panel', () => {
},
});
expect(core.http.get).toHaveBeenCalledWith('/api/lens/existing_fields/a', {
expect(core.http.get).toHaveBeenCalledWith({
path: '/api/lens/existing_fields/a',
query: {
fromDate: '2019-01-01',
toDate: '2020-01-02',
@ -436,7 +438,8 @@ describe('IndexPattern Data Panel', () => {
expect(setState).toHaveBeenCalledTimes(2);
expect(core.http.get).toHaveBeenCalledWith('/api/lens/existing_fields/a', {
expect(core.http.get).toHaveBeenCalledWith({
path: '/api/lens/existing_fields/a',
query: {
fromDate: '2019-01-01',
toDate: '2020-01-01',
@ -444,7 +447,8 @@ describe('IndexPattern Data Panel', () => {
},
});
expect(core.http.get).toHaveBeenCalledWith('/api/lens/existing_fields/b', {
expect(core.http.get).toHaveBeenCalledWith({
path: '/api/lens/existing_fields/b',
query: {
fromDate: '2019-01-01',
toDate: '2020-01-01',
@ -484,13 +488,13 @@ describe('IndexPattern Data Panel', () => {
let overlapCount = 0;
const props = testProps();
core.http.get.mockImplementation((url: string) => {
core.http.get.mockImplementation(({ path }) => {
if (queryCount) {
++overlapCount;
}
++queryCount;
const parts = url.split('/');
const parts = path.split('/');
const indexPatternTitle = parts[parts.length - 1];
const result = Promise.resolve({
indexPatternTitle,

View file

@ -537,8 +537,8 @@ describe('loader', () => {
describe('syncExistingFields', () => {
it('should call once for each index pattern', async () => {
const setState = jest.fn();
const fetchJson = jest.fn(async (url: string) => {
const indexPatternTitle = _.last(url.split('/'));
const fetchJson = jest.fn(({ path }: { path: string }) => {
const indexPatternTitle = _.last(path.split('/'));
return {
indexPatternTitle,
existingFieldNames: ['field_1', 'field_2'].map(

View file

@ -235,7 +235,8 @@ export async function syncExistingFields({
query.timeFieldName = pattern.timeFieldName;
}
return fetchJson(`${BASE_API_URL}/existing_fields/${pattern.id}`, {
return fetchJson({
path: `${BASE_API_URL}/existing_fields/${pattern.id}`,
query,
}) as Promise<ExistingFields>;
})

View file

@ -5,8 +5,6 @@
*/
import { kfetch } from 'ui/kfetch';
// @ts-ignore
import { addSystemApiHeader } from 'ui/system_api';
const API_BASE_URL = '/api/reporting/jobs';
@ -64,7 +62,7 @@ class JobQueueClient {
method: 'GET',
pathname: `${API_BASE_URL}/list`,
query,
headers: addSystemApiHeader({}),
asSystemRequest: true,
});
};
@ -72,7 +70,7 @@ class JobQueueClient {
return kfetch({
method: 'GET',
pathname: `${API_BASE_URL}/count`,
headers: addSystemApiHeader({}),
asSystemRequest: true,
});
}
@ -80,7 +78,7 @@ class JobQueueClient {
return kfetch({
method: 'GET',
pathname: `${API_BASE_URL}/output/${jobId}`,
headers: addSystemApiHeader({}),
asSystemRequest: true,
});
}
@ -88,7 +86,7 @@ class JobQueueClient {
return kfetch({
method: 'GET',
pathname: `${API_BASE_URL}/info/${jobId}`,
headers: addSystemApiHeader({}),
asSystemRequest: true,
});
}
}

View file

@ -16,6 +16,7 @@ const buildRequest = (path = '/app/kibana') => {
return {
path,
route: { settings: {} },
headers: {},
raw: {
req: {
socket: {},

View file

@ -64,10 +64,8 @@ describe('licensing plugin', () => {
await refresh();
expect(coreSetup.http.get.mock.calls[0][1]).toMatchObject({
headers: {
'kbn-system-api': 'true',
},
expect(coreSetup.http.get.mock.calls[0][0]).toMatchObject({
asSystemRequest: true,
});
});
});

View file

@ -132,10 +132,9 @@ export class LicensingPlugin implements Plugin<LicensingPluginSetup> {
private fetchLicense = async (core: CoreSetup): Promise<ILicense> => {
try {
const response = await core.http.get(this.infoEndpoint, {
headers: {
'kbn-system-api': 'true',
},
const response = await core.http.get({
path: this.infoEndpoint,
asSystemRequest: true,
});
return new License({
license: response.license,

View file

@ -23,7 +23,7 @@ export class AuthenticationService {
return {
async getCurrentUser() {
return (await http.get('/internal/security/me', {
headers: { 'kbn-system-api': true },
asSystemRequest: true,
})) as AuthenticatedUser;
},
};

View file

@ -155,7 +155,7 @@ function getProps({
const { fatalErrors } = coreMock.createSetup();
const { http, docLinks, notifications } = coreMock.createStart();
http.get.mockImplementation(async path => {
http.get.mockImplementation(async (path: any) => {
if (path === '/api/features') {
return buildFeatures();
}
@ -509,7 +509,7 @@ describe('<EditRolePage />', () => {
it('can render if features are not available', async () => {
const { http } = coreMock.createStart();
http.get.mockImplementation(async path => {
http.get.mockImplementation(async (path: any) => {
if (path === '/api/features') {
const error = { response: { status: 404 } };
throw error;

View file

@ -16,7 +16,7 @@ describe('RolesAPIClient', () => {
await rolesAPIClient.saveRole({ role, spacesEnabled });
expect(httpMock.put).toHaveBeenCalledTimes(1);
return JSON.parse(httpMock.put.mock.calls[0][1]?.body as any);
return JSON.parse((httpMock.put.mock.calls[0] as any)[1]?.body as any);
}
describe('spaces disabled', () => {

View file

@ -104,9 +104,8 @@ export class SessionTimeout implements ISessionTimeout {
*/
private fetchSessionInfoAndResetTimers = async (extend = false) => {
const method = extend ? 'POST' : 'GET';
const headers = extend ? {} : { 'kbn-system-api': 'true' };
try {
const result = await this.http.fetch(SESSION_ROUTE, { method, headers });
const result = await this.http.fetch(SESSION_ROUTE, { method, asSystemRequest: !extend });
this.handleSessionInfoAndResetTimers(result);

View file

@ -58,7 +58,7 @@ describe('response', () => {
http.intercept(interceptor);
fetchMock.mock('*', 200);
await http.fetch('/foo-api', { headers: { 'kbn-system-api': 'true' } });
await http.fetch('/foo-api', { asSystemRequest: true });
expect(sessionTimeoutMock.extend).not.toHaveBeenCalled();
});
@ -99,9 +99,9 @@ describe('responseError', () => {
http.intercept(interceptor);
fetchMock.mock('*', 401);
await expect(
http.fetch('/foo-api', { headers: { 'kbn-system-api': 'true' } })
).rejects.toMatchInlineSnapshot(`[Error: Unauthorized]`);
await expect(http.fetch('/foo-api', { asSystemRequest: true })).rejects.toMatchInlineSnapshot(
`[Error: Unauthorized]`
);
expect(sessionTimeoutMock.extend).not.toHaveBeenCalled();
});

View file

@ -6,38 +6,34 @@
import {
HttpInterceptor,
HttpErrorResponse,
IHttpResponse,
HttpInterceptorResponseError,
HttpResponse,
IAnonymousPaths,
} from 'src/core/public';
import { ISessionTimeout } from './session_timeout';
const isSystemAPIRequest = (request: Request) => {
return request.headers.has('kbn-system-api');
};
export class SessionTimeoutHttpInterceptor implements HttpInterceptor {
constructor(private sessionTimeout: ISessionTimeout, private anonymousPaths: IAnonymousPaths) {}
response(httpResponse: IHttpResponse) {
response(httpResponse: HttpResponse) {
if (this.anonymousPaths.isAnonymous(window.location.pathname)) {
return;
}
if (isSystemAPIRequest(httpResponse.request)) {
if (httpResponse.fetchOptions.asSystemRequest) {
return;
}
this.sessionTimeout.extend(httpResponse.request.url);
}
responseError(httpErrorResponse: HttpErrorResponse) {
responseError(httpErrorResponse: HttpInterceptorResponseError) {
if (this.anonymousPaths.isAnonymous(window.location.pathname)) {
return;
}
if (isSystemAPIRequest(httpErrorResponse.request)) {
if (httpErrorResponse.fetchOptions.asSystemRequest) {
return;
}

View file

@ -6,7 +6,7 @@
import {
HttpInterceptor,
HttpErrorResponse,
HttpInterceptorResponseError,
IHttpInterceptController,
IAnonymousPaths,
} from 'src/core/public';
@ -16,7 +16,10 @@ import { SessionExpired } from './session_expired';
export class UnauthorizedResponseHttpInterceptor implements HttpInterceptor {
constructor(private sessionExpired: SessionExpired, private anonymousPaths: IAnonymousPaths) {}
responseError(httpErrorResponse: HttpErrorResponse, controller: IHttpInterceptController) {
responseError(
httpErrorResponse: HttpInterceptorResponseError,
controller: IHttpInterceptController
) {
if (this.anonymousPaths.isAnonymous(window.location.pathname)) {
return;
}