Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
a140b8a
Add filter for cache-invalidating request headers
maxschmeling Aug 18, 2026
bf3dfe4
Document cache header security implications
maxschmeling Aug 18, 2026
a205f96
Rename cache key request headers filter
maxschmeling Aug 18, 2026
40c6544
Configure cache key headers per data source and query
maxschmeling Aug 18, 2026
29c7ecb
Preserve cache headers for custom queries and logs
maxschmeling Aug 18, 2026
6c8fd10
Consolidate cache key headers on queries
maxschmeling Aug 18, 2026
4981d3f
Document HttpQueryInterface upgrade
maxschmeling Aug 18, 2026
dafd919
Simplify cache key header metadata flow
maxschmeling Aug 18, 2026
a1c7e51
Apply suggestion from @chriszarate
maxschmeling Aug 18, 2026
bb1a106
Remove unused CacheKeyRequestHeaders reference
maxschmeling Aug 18, 2026
44f1b25
Update the shape of CacheKeyRequestHeaders::merge
maxschmeling Aug 18, 2026
1738a00
Fix local review issues and old constant refs
maxschmeling Aug 18, 2026
b94db2f
Regenerate AI docs after example updates
maxschmeling Aug 18, 2026
1cde10a
Own the remote data cache strategy
maxschmeling Aug 18, 2026
52bc96e
Preserve HTTP logger options
maxschmeling Aug 18, 2026
be07ab9
Preserve custom HTTP query compatibility
maxschmeling Aug 18, 2026
9ae5731
Own cache TTL request header
maxschmeling Aug 18, 2026
78741db
Remove unnecessary __invoke
maxschmeling Aug 19, 2026
6f5bfe3
Remove unused reference
maxschmeling Aug 19, 2026
e9b5dc5
Restore cache metadata stripping
maxschmeling Aug 19, 2026
fea0af2
Strip internal cache metadata headers
maxschmeling Aug 19, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions docs/concepts/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ This plugin offers a caching layer for optimal performance. It will be used if y

The default TTL for all cache objects is 5 minutes, but it can be [configured per query or request](../extending/query.md#cache_ttl-intnullcallable). Error responses are cached for 30 seconds to avoid overwhelming the remote data source under error conditions. Multiple requests for the same data within a single page load will be deduplicated even if the requests are not cacheable.

### Cache isolation and custom request headers

The response cache is shared across queries. When the site uses a persistent object cache, it is also shared across requests and users. Cache entries distinguish requests by their method, URI, body, and a configured list of request headers. `Authorization` and `Cache-Control` are included in that list by default, but arbitrary request headers are not included automatically.

**Security warning:** If an API uses a custom header for authentication, authorization, tenancy, or any other value that changes the response, that header must be added to the cache key. Otherwise, requests that differ only by that header can share a cache entry. With a persistent object cache, this can cause a response fetched with one credential or security context to be returned to a request using another, potentially exposing protected remote data.

Use the data source or query [`cache_key_request_headers`](../extending/data-source.md#cache_key_request_headers-array) configuration to add every custom header that can affect the authorized or returned data. Data-source entries apply to every query that uses that source; query entries are merged for one query. The built-in defaults cannot be removed.

## Technical concepts

If you want to understand the internals of Remote Data Blocks so that you can write code to extend its functionality, head over to the [extending guide](../extending/index.md).
Expand Down
13 changes: 13 additions & 0 deletions docs/extending/data-source.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ $data_source = [
'Content-Type' => 'application/json',
'X-Api-Key' => constant( 'MY_API_KEY_CONSTANT' ),
],
'cache_key_request_headers' => [ 'X-Api-Key' ],
];
```

Expand Down Expand Up @@ -72,6 +73,18 @@ An associative array of headers that will be sent with each HTTP request. Querie

When providing authentication credentials, take care to avoid committing them to code repositories. We strongly recommend using environment variables or secure storage.

### cache_key_request_headers: array

A static list of request header names whose values will be included in object cache keys for every query that uses this data source. `Authorization` and `Cache-Control` are always included by default. Query-level entries are added to the data-source list, and duplicate names are removed case-insensitively. A configured header that is absent from a request is ignored.

```php
'cache_key_request_headers' => [ 'X-Api-Key', 'X-Tenant-ID' ],
```

**Security warning:** Add every custom header that can affect authentication, authorization, tenancy, or the returned data. If two requests have the same method, URI, and body but use different values for an omitted header, one request can receive the response cached for the other. With a persistent object cache, this can expose protected data across requests and users.

For Generic HTTP data sources configured in the plugin settings, custom API-key authentication headers are added automatically. Use the **Additional cache key headers** field for other authentication, tenancy, or response-varying headers. Shopify's storefront access-token header is also included automatically.

### Next steps

After defining a data source in code, you can use it in a [query](query.md) to define how data is retrieved.
10 changes: 10 additions & 0 deletions docs/extending/query.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,16 @@ The `request_headers` property defines the request headers for the query. It can
},
```

### cache_key_request_headers: array

A static list of additional request header names whose values will be included in the object cache key for this query. `Authorization` and `Cache-Control` are always included by default. Query entries are added to the list configured by the data source, and duplicate names are removed case-insensitively. A configured header that is absent from a request is ignored.

```php
'cache_key_request_headers' => [ 'X-Request-Scope' ],
```

**Security warning:** Add every query-specific header that can affect authentication, authorization, tenancy, or the returned data. Omitting such a header can allow requests with different security contexts to share a cached response, potentially exposing protected data across requests and users when a persistent object cache is enabled. Prefer the [data-source configuration](data-source.md#cache_key_request_headers-array) when a header applies to every query for that source.

### request_body: array|callable

The `request_body` property defines the request body for the query. It can be an associative array or a callable function that returns an associative array. The callable function accepts an associative array of input variables (`[ $var_name => $value ]`). If omitted, the query will not have a request body.
Expand Down
12 changes: 12 additions & 0 deletions inc/Config/CacheKeyRequestHeadersInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php declare(strict_types = 1);

namespace RemoteDataBlocks\Config;

interface CacheKeyRequestHeadersInterface {
Comment thread
chriszarate marked this conversation as resolved.
Outdated
/**
* Get the request header names whose values should be included in cache keys.
*
* @return array<string> Request header names included in cache keys.
*/
public function get_cache_key_request_headers(): array;
}
7 changes: 6 additions & 1 deletion inc/Config/DataSource/HttpDataSource.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace RemoteDataBlocks\Config\DataSource;

use RemoteDataBlocks\Config\ArraySerializable;
use RemoteDataBlocks\Config\CacheKeyRequestHeadersInterface;
use RemoteDataBlocks\Validation\ConfigSchemas;
use RemoteDataBlocks\WpdbStorage\DataSourceCrud;
use WP_Error;
Expand All @@ -12,7 +13,11 @@
*
* Implements the HttpDataSourceInterface to define a generic HTTP data source.
*/
class HttpDataSource extends ArraySerializable implements HttpDataSourceInterface {
class HttpDataSource extends ArraySerializable implements HttpDataSourceInterface, CacheKeyRequestHeadersInterface {
public function get_cache_key_request_headers(): array {
Comment thread
maxschmeling marked this conversation as resolved.
Outdated
return $this->config['cache_key_request_headers'] ?? [];
}

final public function get_display_name(): string {
return $this->config['display_name'];
}
Expand Down
20 changes: 19 additions & 1 deletion inc/Config/Query/HttpQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
namespace RemoteDataBlocks\Config\Query;

use RemoteDataBlocks\Config\ArraySerializable;
use RemoteDataBlocks\Config\CacheKeyRequestHeadersInterface;
use RemoteDataBlocks\Config\DataSource\HttpDataSource;
use RemoteDataBlocks\Config\DataSource\HttpDataSourceInterface;
use RemoteDataBlocks\Config\QueryRunner\QueryRunner;
use RemoteDataBlocks\HttpClient\CacheKeyRequestHeaders;
use RemoteDataBlocks\Validation\ConfigSchemas;
use WP_Error;

Expand All @@ -16,7 +18,7 @@
*
* This class can be used to implement most HTTP queries.
*/
class HttpQuery extends ArraySerializable implements HttpQueryInterface {
class HttpQuery extends ArraySerializable implements HttpQueryInterface, CacheKeyRequestHeadersInterface {
/**
* Execute the query with the provided input variables. Execution can be
* customized by providing a custom query runner.
Expand All @@ -38,6 +40,22 @@ public function execute_batch( array $array_of_input_variables ): array|WP_Error
return $query_runner->execute_batch( $this, $array_of_input_variables );
}

/**
* Get the request header names whose values should be included in cache keys.
*
* @return array<string> Request header names included in cache keys.
*/
public function get_cache_key_request_headers(): array {
$data_source = $this->get_data_source();
$data_source_headers = $data_source instanceof CacheKeyRequestHeadersInterface ? $data_source->get_cache_key_request_headers() : [];

return CacheKeyRequestHeaders::merge(
CacheKeyRequestHeaders::DEFAULT_HEADERS,
$data_source_headers,
$this->config['cache_key_request_headers'] ?? []
);
}

/**
* Define the cache object TTL for the current query execution's responses:
* - Return a positive integer to set a custom TTL in seconds.
Expand Down
12 changes: 12 additions & 0 deletions inc/Config/QueryRunner/QueryRunner.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@

use Exception;
use GuzzleHttp\RequestOptions;
use RemoteDataBlocks\Config\CacheKeyRequestHeadersInterface;
use RemoteDataBlocks\Config\Query\HttpQueryInterface;
use RemoteDataBlocks\Editor\DataBinding\Pagination;
use RemoteDataBlocks\HttpClient\CacheKeyRequestHeaders;
use RemoteDataBlocks\HttpClient\HttpClient;
use RemoteDataBlocks\HttpClient\RdbCacheMiddleware;
use RemoteDataBlocks\HttpClient\RdbCacheStrategy;
use WP_Error;

Expand Down Expand Up @@ -57,6 +60,14 @@ protected function get_request_details( HttpQueryInterface $query, array $input_
$body = $query->get_request_body( $input_variables );
$endpoint = $query->get_endpoint( $input_variables );
$cache_ttl = $query->get_cache_ttl( $input_variables );
$data_source = $query->get_data_source();
$data_source_cache_key_request_headers = $data_source instanceof CacheKeyRequestHeadersInterface ? $data_source->get_cache_key_request_headers() : [];
$query_cache_key_request_headers = $query instanceof CacheKeyRequestHeadersInterface ? $query->get_cache_key_request_headers() : [];
$cache_key_request_headers = CacheKeyRequestHeaders::merge(
CacheKeyRequestHeaders::DEFAULT_HEADERS,
$data_source_cache_key_request_headers,
$query_cache_key_request_headers
);
$parsed_url = wp_parse_url( $endpoint );

if ( false === $parsed_url ) {
Expand Down Expand Up @@ -102,6 +113,7 @@ protected function get_request_details( HttpQueryInterface $query, array $input_
$request_details = [
'method' => $method,
'options' => [
RdbCacheMiddleware::CACHE_KEY_REQUEST_HEADERS_OPTION => $cache_key_request_headers,
RequestOptions::HEADERS => array_merge( $headers, $cache_headers ),
RequestOptions::JSON => $body,
],
Expand Down
32 changes: 32 additions & 0 deletions inc/HttpClient/CacheKeyRequestHeaders.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php declare(strict_types = 1);

namespace RemoteDataBlocks\HttpClient;

final class CacheKeyRequestHeaders {
public const DEFAULT_HEADERS = [ 'Authorization', 'Cache-Control' ];
Comment thread
maxschmeling marked this conversation as resolved.
Outdated

/**
* Merge request header name lists without case-insensitive duplicates.
*
* @param array<string> ...$header_lists Request header name lists.
* @return array<string> Merged request header names.
*/
public static function merge( array ...$header_lists ): array {
$merged_headers = [];
$seen_headers = [];

foreach ( $header_lists as $header_list ) {
foreach ( $header_list as $header ) {
$normalized_header = strtolower( $header );
if ( isset( $seen_headers[ $normalized_header ] ) ) {
continue;
}

$seen_headers[ $normalized_header ] = true;
$merged_headers[] = $header;
}
}

return $merged_headers;
Comment thread
maxschmeling marked this conversation as resolved.
Outdated
}
}
24 changes: 24 additions & 0 deletions inc/HttpClient/RdbCacheMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,31 @@

namespace RemoteDataBlocks\HttpClient;

use Psr\Http\Message\RequestInterface;

class RdbCacheMiddleware extends \Kevinrob\GuzzleCache\CacheMiddleware {
public const CACHE_KEY_REQUEST_HEADERS_HEADER = 'X-Remote-Data-Blocks-Cache-Key-Headers';
Comment thread
chriszarate marked this conversation as resolved.
Outdated
public const CACHE_KEY_REQUEST_HEADERS_OPTION = 'remote_data_blocks_cache_key_request_headers';

public function __invoke( callable $handler ): callable {
Comment thread
maxschmeling marked this conversation as resolved.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I understand what is accomplished by this __invoke override. I believe this header is already removed by the RdbCacheStrategy#getCacheObject

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left over duplicate. I've removed it.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The __invoke is still present

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be clear, I don't think this __invoke has any effect. Can you test this?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't. I removed it but didn't get that in the commit I guess. Pushed in 78741db

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This removal actually does cause a test failure.

get_cache_object() removes the header from the request stored in the cache entry, but it runs only after the downstream HTTP handler has returned. This override wraps that handler so the cache strategy can still use the metadata while the transport receives a sanitized request. Without it, the metadata header is sent to the remote API, as covered by testCacheKeyRequestHeaderMetadataIsNotSentToRequestHandler.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also realized this means the TTL value isn't being stripped either. So I've added a test and fix for that as well.

fea0af2

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without it, the metadata header is sent to the remote API

The same is probably true of X-Remote-Data-Blocks-Cache-TTL. Is that bad?

@chriszarate chriszarate Aug 19, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure it is a bad side effect. It's just a request header. But we should pick a policy and be consistent. I'd vote to leave it personally.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I already removed it in the commit I commented above.

I definitely don't think we should be adding headers to requests for internal functions and letting them flow through to the endpoint. Unless you have strong opinions about it, I'm going to go with the approach of stripping them.

$handler_without_cache_metadata = function ( RequestInterface $request, array $options ) use ( $handler ) {
return $handler( $request->withoutHeader( self::CACHE_KEY_REQUEST_HEADERS_HEADER ), $options );
};
$cache_handler = parent::__invoke( $handler_without_cache_metadata );

return function ( RequestInterface $request, array $options ) use ( $cache_handler ) {
$cache_key_request_headers = $options[ self::CACHE_KEY_REQUEST_HEADERS_OPTION ] ?? [];
unset( $options[ self::CACHE_KEY_REQUEST_HEADERS_OPTION ] );

if ( is_array( $cache_key_request_headers ) ) {
$cache_key_request_headers = array_values( array_filter( $cache_key_request_headers, 'is_string' ) );
$request = $request->withHeader( self::CACHE_KEY_REQUEST_HEADERS_HEADER, $cache_key_request_headers );
}

return $cache_handler( $request, $options );
};
}

/**
* @var array<string, true>
*/
Expand Down
21 changes: 13 additions & 8 deletions inc/HttpClient/RdbCacheStrategy.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,11 @@ class RdbCacheStrategy extends GreedyCacheStrategy {
public const CACHE_TTL_REQUEST_HEADER = GreedyCacheStrategy::HEADER_TTL;
public const WP_OBJECT_CACHE_GROUP = 'remote-data-blocks';

private const CACHE_INVALIDATING_REQUEST_HEADERS = [ 'Authorization', 'Cache-Control' ];
private const ERROR_CACHE_TTL_IN_SECONDS = 30; // 30 seconds for error responses
private const FALLBACK_CACHE_TTL_IN_SECONDS = 300; // 5 minutes for success responses

public function __construct( ?CacheStorageInterface $storage = null ) {
// Filter this if customization is needed.
$vary_headers = new KeyValueHttpHeader( self::CACHE_INVALIDATING_REQUEST_HEADERS );
$vary_headers = new KeyValueHttpHeader( CacheKeyRequestHeaders::DEFAULT_HEADERS );

parent::__construct(
$storage ?? new WordPressObjectCacheStorage( self::WP_OBJECT_CACHE_GROUP ),
Expand All @@ -34,16 +32,23 @@ public function __construct( ?CacheStorageInterface $storage = null ) {
);
}

public static function get_object_cache_key_from_request( RequestInterface $request ): string {
/**
* @param array<string>|null $cache_key_request_headers Request headers included in the cache key. When omitted, read them from the request metadata header.
*/
public static function get_object_cache_key_from_request( RequestInterface $request, ?array $cache_key_request_headers = null ): string {
$request_body = (string) $request->getBody();
$request_headers = $request->getHeaders();
$request_method = $request->getMethod();
$request_uri = (string) $request->getUri();

$cache_key_request_headers = CacheKeyRequestHeaders::merge(
CacheKeyRequestHeaders::DEFAULT_HEADERS,
$cache_key_request_headers ?? $request->getHeader( RdbCacheMiddleware::CACHE_KEY_REQUEST_HEADERS_HEADER )
);

$cache_headers = [];
foreach ( self::CACHE_INVALIDATING_REQUEST_HEADERS as $header ) {
if ( isset( $request_headers[ $header ] ) ) {
$cache_headers[ $header ] = $request_headers[ $header ];
foreach ( $cache_key_request_headers as $header ) {
if ( $request->hasHeader( $header ) ) {
$cache_headers[ $header ] = $request->getHeader( $header );
}
}

Expand Down
6 changes: 4 additions & 2 deletions inc/HttpClient/RdbLogMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,16 @@ public function __invoke( callable $handler ): callable {
};
}

private function log( RequestInterface $request, ?ResponseInterface $response, ?\Exception $reason ): void {
private function log( RequestInterface $request, ?ResponseInterface $response, ?\Exception $reason, array $options ): void {
$response_headers = $response ? $response->getHeaders() : [];
$uri = $request->getUri();
$cache_key_request_headers = $options[ RdbCacheMiddleware::CACHE_KEY_REQUEST_HEADERS_OPTION ] ?? [];
$cache_key_request_headers = is_array( $cache_key_request_headers ) ? array_values( array_filter( $cache_key_request_headers, 'is_string' ) ) : [];

$context = [
'cache_age' => $response_headers[ RdbCacheStrategy::CACHE_AGE_RESPONSE_HEADER ][0] ?? '',
'cache_group' => RdbCacheStrategy::WP_OBJECT_CACHE_GROUP ?? '',
'cache_key' => RdbCacheStrategy::get_object_cache_key_from_request( $request ),
'cache_key' => RdbCacheStrategy::get_object_cache_key_from_request( $request, $cache_key_request_headers ),
'cache_status' => $response_headers[ CacheMiddleware::HEADER_CACHE_INFO ][0] ?? '',
'error' => $reason,
'hostname' => $uri->getHost(),
Expand Down
10 changes: 10 additions & 0 deletions inc/Integrations/GenericHttp/GenericHttpDataSource.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace RemoteDataBlocks\Integrations\GenericHttp;

use RemoteDataBlocks\Config\DataSource\HttpDataSource;
use RemoteDataBlocks\HttpClient\CacheKeyRequestHeaders;
use RemoteDataBlocks\Validation\Types;
use RemoteDataBlocks\Validation\Validator;
use RemoteDataBlocks\Validation\ConfigSchemas;
Expand All @@ -23,6 +24,7 @@ protected static function get_service_config_schema(): array {
'value' => Types::skip_sanitize( Types::string() ),
] )
),
'cache_key_request_headers' => Types::nullable( Types::list_of( Types::string() ) ),
'display_name' => Types::string(),
'endpoint' => Types::string(),
] );
Expand Down Expand Up @@ -64,12 +66,20 @@ public static function get_request_headers_from_service_config( array $service_c
return [];
}

public static function get_cache_key_request_headers_from_service_config( array $service_config ): array {
return CacheKeyRequestHeaders::merge(
array_keys( self::get_request_headers_from_service_config( $service_config ) ),
$service_config['cache_key_request_headers'] ?? []
);
}

final public function get_service_name(): string {
return static::SERVICE_NAME;
}

protected static function map_service_config( array $service_config ): array {
return [
'cache_key_request_headers' => self::get_cache_key_request_headers_from_service_config( $service_config ),
'display_name' => $service_config['display_name'],
'endpoint' => self::get_endpoint_from_service_config( $service_config ),
'request_headers' => self::get_request_headers_from_service_config( $service_config ),
Expand Down
1 change: 1 addition & 0 deletions inc/Integrations/Shopify/ShopifyDataSource.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ protected static function map_service_config( array $service_config ): array {
}

return [
'cache_key_request_headers' => [ 'X-Shopify-Storefront-Access-Token' ],
'display_name' => $service_config['display_name'],
'endpoint' => $endpoint,
'image_url' => plugins_url( './assets/shopify_logo_black.png', __FILE__ ),
Expand Down
2 changes: 2 additions & 0 deletions inc/Validation/ConfigSchemas.php
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ private static function generate_graphql_query_config_schema(): array {

private static function generate_http_data_source_config_schema(): array {
return Types::object( [
'cache_key_request_headers' => Types::nullable( Types::list_of( Types::string() ) ),
'display_name' => Types::string(),
'endpoint' => Types::string(),
'image_url' => Types::nullable( Types::image_url() ),
Expand All @@ -159,6 +160,7 @@ private static function generate_http_query_config_schema(): array {
return Types::object( [
'display_name' => Types::nullable( Types::string() ),
'cache_ttl' => Types::nullable( Types::one_of( Types::callable(), Types::integer(), Types::null() ) ),
'cache_key_request_headers' => Types::nullable( Types::list_of( Types::string() ) ),
'data_source' => Types::one_of(
Types::instance_of( HttpDataSource::class ),
Types::serialized_config_for( HttpDataSource::class ),
Expand Down
21 changes: 21 additions & 0 deletions src/data-sources/http/HttpSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Card, CardBody, ExternalLink, TextControl, Tip } from '@wordpress/compo
import { __ } from '@wordpress/i18n';

import { DataSourceForm } from '../components/DataSourceForm';
import { CustomFormFieldToken } from '@/data-sources/components/CustomFormFieldToken';
import { HttpAuthSettingsInput } from '@/data-sources/components/HttpAuthSettingsInput';
import { ConfigSource } from '@/data-sources/constants';
import { useDataSources } from '@/data-sources/hooks/useDataSources';
Expand Down Expand Up @@ -93,6 +94,26 @@ export const HttpSettings = ( { mode, uuid, config }: SettingsComponentProps< Ht
/>

<HttpAuthSettingsInput auth={ state.auth } onChange={ handleAuthOnChange } />
<CustomFormFieldToken
label={ __( 'Additional cache key headers', 'remote-data-blocks' ) }
value={ state.cache_key_request_headers ?? [] }
onChange={ ( headers: Array< string | { value: string } > ) => {
handleOnChange(
'cache_key_request_headers',
headers.map( header => ( 'object' === typeof header ? header.value : header ) )
);
} }
suggestions={ [] }
__experimentalValidateInput={ ( input: string ) =>
/^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/.test( input )
}
__nextHasNoMarginBottom
__next40pxDefaultSize
customHelpText={ __(
'Custom authentication headers configured above are included automatically. Add every other header that can affect authentication, authorization, tenancy, or returned data. Omitting one can expose cached data across security contexts.',
'remote-data-blocks'
) }
/>
<Card style={ { marginTop: '16px' } }>
<CardBody>
<Tip>
Expand Down
Loading
Loading