Add configurable API rate limits with subtabs in settings (v0.10.0)
- Make rate limiting configurable via WordPress options - Add subtabs to API settings: General, Rate Limits, Endpoints - Add HTTP method badges for endpoint documentation - Update CHANGELOG with rate limiting configuration details Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -22,23 +22,61 @@ final class RateLimiter {
|
||||
private const TRANSIENT_PREFIX = 'wp_bnb_rate_';
|
||||
|
||||
/**
|
||||
* Rate limits per minute by endpoint type.
|
||||
* Default rate limits per minute by endpoint type.
|
||||
*
|
||||
* @var array<string, int>
|
||||
*/
|
||||
private array $limits = array(
|
||||
private const DEFAULT_LIMITS = array(
|
||||
'public' => 60, // Public read endpoints.
|
||||
'availability' => 30, // Availability checks.
|
||||
'booking' => 10, // Booking creation.
|
||||
'admin' => 120, // Admin endpoints.
|
||||
);
|
||||
|
||||
/**
|
||||
* Rate limits per minute by endpoint type.
|
||||
*
|
||||
* @var array<string, int>
|
||||
*/
|
||||
private array $limits;
|
||||
|
||||
/**
|
||||
* Time window in seconds.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private int $window = 60;
|
||||
private int $window;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->load_limits_from_options();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load rate limits from WordPress options.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function load_limits_from_options(): void {
|
||||
$this->limits = array(
|
||||
'public' => (int) get_option( 'wp_bnb_rate_limit_public', self::DEFAULT_LIMITS['public'] ),
|
||||
'availability' => (int) get_option( 'wp_bnb_rate_limit_availability', self::DEFAULT_LIMITS['availability'] ),
|
||||
'booking' => (int) get_option( 'wp_bnb_rate_limit_booking', self::DEFAULT_LIMITS['booking'] ),
|
||||
'admin' => (int) get_option( 'wp_bnb_rate_limit_admin', self::DEFAULT_LIMITS['admin'] ),
|
||||
);
|
||||
$this->window = (int) get_option( 'wp_bnb_rate_limit_window', 60 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default rate limits.
|
||||
*
|
||||
* @return array<string, int>
|
||||
*/
|
||||
public static function get_default_limits(): array {
|
||||
return self::DEFAULT_LIMITS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if request is within rate limit.
|
||||
|
||||
451
src/Plugin.php
451
src/Plugin.php
@@ -1460,147 +1460,319 @@ final class Plugin {
|
||||
* @return void
|
||||
*/
|
||||
private function render_api_settings(): void {
|
||||
$api_enabled = get_option( 'wp_bnb_api_enabled', 'yes' );
|
||||
$rate_limiting = get_option( 'wp_bnb_api_rate_limiting', 'yes' );
|
||||
$api_base_url = rest_url( RestApi::NAMESPACE );
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Subtab switching only.
|
||||
$active_subtab = isset( $_GET['subtab'] ) ? sanitize_key( $_GET['subtab'] ) : 'general';
|
||||
|
||||
$api_enabled = get_option( 'wp_bnb_api_enabled', 'yes' );
|
||||
$rate_limiting = get_option( 'wp_bnb_api_rate_limiting', 'yes' );
|
||||
$api_base_url = rest_url( RestApi::NAMESPACE );
|
||||
|
||||
// Rate limit values.
|
||||
$defaults = \Magdev\WpBnb\Api\RateLimiter::get_default_limits();
|
||||
$limit_public = get_option( 'wp_bnb_rate_limit_public', $defaults['public'] );
|
||||
$limit_avail = get_option( 'wp_bnb_rate_limit_availability', $defaults['availability'] );
|
||||
$limit_booking = get_option( 'wp_bnb_rate_limit_booking', $defaults['booking'] );
|
||||
$limit_admin = get_option( 'wp_bnb_rate_limit_admin', $defaults['admin'] );
|
||||
$limit_window = get_option( 'wp_bnb_rate_limit_window', 60 );
|
||||
|
||||
$base_url = admin_url( 'admin.php?page=wp-bnb-settings&tab=api' );
|
||||
?>
|
||||
|
||||
<!-- API Subtabs -->
|
||||
<div class="wp-bnb-subtabs">
|
||||
<a href="<?php echo esc_url( $base_url . '&subtab=general' ); ?>"
|
||||
class="wp-bnb-subtab <?php echo 'general' === $active_subtab ? 'active' : ''; ?>">
|
||||
<span class="dashicons dashicons-admin-generic"></span>
|
||||
<?php esc_html_e( 'General', 'wp-bnb' ); ?>
|
||||
</a>
|
||||
<a href="<?php echo esc_url( $base_url . '&subtab=rate-limits' ); ?>"
|
||||
class="wp-bnb-subtab <?php echo 'rate-limits' === $active_subtab ? 'active' : ''; ?>">
|
||||
<span class="dashicons dashicons-dashboard"></span>
|
||||
<?php esc_html_e( 'Rate Limits', 'wp-bnb' ); ?>
|
||||
</a>
|
||||
<a href="<?php echo esc_url( $base_url . '&subtab=endpoints' ); ?>"
|
||||
class="wp-bnb-subtab <?php echo 'endpoints' === $active_subtab ? 'active' : ''; ?>">
|
||||
<span class="dashicons dashicons-rest-api"></span>
|
||||
<?php esc_html_e( 'Endpoints', 'wp-bnb' ); ?>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<form method="post" action="">
|
||||
<?php wp_nonce_field( 'wp_bnb_save_settings', 'wp_bnb_settings_nonce' ); ?>
|
||||
|
||||
<h2><?php esc_html_e( 'REST API Settings', 'wp-bnb' ); ?></h2>
|
||||
<?php if ( 'general' === $active_subtab ) : ?>
|
||||
<!-- General Subtab -->
|
||||
<h2><?php esc_html_e( 'REST API Settings', 'wp-bnb' ); ?></h2>
|
||||
|
||||
<table class="form-table">
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e( 'Enable API', 'wp-bnb' ); ?></th>
|
||||
<td>
|
||||
<label>
|
||||
<input type="checkbox" name="wp_bnb_api_enabled" value="yes" <?php checked( $api_enabled, 'yes' ); ?>>
|
||||
<?php esc_html_e( 'Enable the REST API endpoints', 'wp-bnb' ); ?>
|
||||
</label>
|
||||
<p class="description">
|
||||
<?php esc_html_e( 'When enabled, external applications can access room, availability, and booking data via the API.', 'wp-bnb' ); ?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e( 'Rate Limiting', 'wp-bnb' ); ?></th>
|
||||
<td>
|
||||
<label>
|
||||
<input type="checkbox" name="wp_bnb_api_rate_limiting" value="yes" <?php checked( $rate_limiting, 'yes' ); ?>>
|
||||
<?php esc_html_e( 'Enable rate limiting', 'wp-bnb' ); ?>
|
||||
</label>
|
||||
<p class="description">
|
||||
<?php esc_html_e( 'Limits API requests to prevent abuse. Recommended for production sites.', 'wp-bnb' ); ?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2 style="margin-top: 30px;"><?php esc_html_e( 'API Information', 'wp-bnb' ); ?></h2>
|
||||
|
||||
<table class="form-table">
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e( 'Base URL', 'wp-bnb' ); ?></th>
|
||||
<td>
|
||||
<code><?php echo esc_html( $api_base_url ); ?></code>
|
||||
<p class="description">
|
||||
<?php esc_html_e( 'All API endpoints are prefixed with this URL.', 'wp-bnb' ); ?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e( 'API Version', 'wp-bnb' ); ?></th>
|
||||
<td>
|
||||
<code><?php echo esc_html( RestApi::VERSION ); ?></code>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e( 'Info Endpoint', 'wp-bnb' ); ?></th>
|
||||
<td>
|
||||
<code><?php echo esc_html( $api_base_url . '/info' ); ?></code>
|
||||
<p class="description">
|
||||
<?php esc_html_e( 'Returns API information and available endpoints.', 'wp-bnb' ); ?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2 style="margin-top: 30px;"><?php esc_html_e( 'Available Endpoints', 'wp-bnb' ); ?></h2>
|
||||
|
||||
<h3><?php esc_html_e( 'Public Endpoints', 'wp-bnb' ); ?></h3>
|
||||
<table class="widefat" style="margin-bottom: 20px;">
|
||||
<thead>
|
||||
<table class="form-table">
|
||||
<tr>
|
||||
<th><?php esc_html_e( 'Method', 'wp-bnb' ); ?></th>
|
||||
<th><?php esc_html_e( 'Endpoint', 'wp-bnb' ); ?></th>
|
||||
<th><?php esc_html_e( 'Description', 'wp-bnb' ); ?></th>
|
||||
<th scope="row"><?php esc_html_e( 'Enable API', 'wp-bnb' ); ?></th>
|
||||
<td>
|
||||
<label>
|
||||
<input type="checkbox" name="wp_bnb_api_enabled" value="yes" <?php checked( $api_enabled, 'yes' ); ?>>
|
||||
<?php esc_html_e( 'Enable the REST API endpoints', 'wp-bnb' ); ?>
|
||||
</label>
|
||||
<p class="description">
|
||||
<?php esc_html_e( 'When enabled, external applications can access room, availability, and booking data via the API.', 'wp-bnb' ); ?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td>GET</td><td><code>/buildings</code></td><td><?php esc_html_e( 'List all buildings', 'wp-bnb' ); ?></td></tr>
|
||||
<tr><td>GET</td><td><code>/buildings/{id}</code></td><td><?php esc_html_e( 'Get building details', 'wp-bnb' ); ?></td></tr>
|
||||
<tr><td>GET</td><td><code>/buildings/{id}/rooms</code></td><td><?php esc_html_e( 'List rooms in building', 'wp-bnb' ); ?></td></tr>
|
||||
<tr><td>GET</td><td><code>/rooms</code></td><td><?php esc_html_e( 'List/search rooms', 'wp-bnb' ); ?></td></tr>
|
||||
<tr><td>GET</td><td><code>/rooms/{id}</code></td><td><?php esc_html_e( 'Get room details', 'wp-bnb' ); ?></td></tr>
|
||||
<tr><td>GET</td><td><code>/rooms/{id}/availability</code></td><td><?php esc_html_e( 'Check room availability', 'wp-bnb' ); ?></td></tr>
|
||||
<tr><td>GET</td><td><code>/rooms/{id}/calendar</code></td><td><?php esc_html_e( 'Get room calendar', 'wp-bnb' ); ?></td></tr>
|
||||
<tr><td>POST</td><td><code>/availability/search</code></td><td><?php esc_html_e( 'Search available rooms', 'wp-bnb' ); ?></td></tr>
|
||||
<tr><td>GET</td><td><code>/services</code></td><td><?php esc_html_e( 'List services', 'wp-bnb' ); ?></td></tr>
|
||||
<tr><td>POST</td><td><code>/pricing/calculate</code></td><td><?php esc_html_e( 'Calculate booking price', 'wp-bnb' ); ?></td></tr>
|
||||
<tr><td>POST</td><td><code>/bookings</code></td><td><?php esc_html_e( 'Create booking (pending status)', 'wp-bnb' ); ?></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h3><?php esc_html_e( 'Admin Endpoints (Requires Authentication)', 'wp-bnb' ); ?></h3>
|
||||
<table class="widefat" style="margin-bottom: 20px;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php esc_html_e( 'Method', 'wp-bnb' ); ?></th>
|
||||
<th><?php esc_html_e( 'Endpoint', 'wp-bnb' ); ?></th>
|
||||
<th><?php esc_html_e( 'Description', 'wp-bnb' ); ?></th>
|
||||
<th scope="row"><?php esc_html_e( 'Rate Limiting', 'wp-bnb' ); ?></th>
|
||||
<td>
|
||||
<label>
|
||||
<input type="checkbox" name="wp_bnb_api_rate_limiting" value="yes" <?php checked( $rate_limiting, 'yes' ); ?>>
|
||||
<?php esc_html_e( 'Enable rate limiting', 'wp-bnb' ); ?>
|
||||
</label>
|
||||
<p class="description">
|
||||
<?php esc_html_e( 'Limits API requests to prevent abuse. Recommended for production sites.', 'wp-bnb' ); ?>
|
||||
<?php if ( 'yes' === $rate_limiting ) : ?>
|
||||
<a href="<?php echo esc_url( $base_url . '&subtab=rate-limits' ); ?>"><?php esc_html_e( 'Configure limits', 'wp-bnb' ); ?> →</a>
|
||||
<?php endif; ?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td>GET</td><td><code>/bookings</code></td><td><?php esc_html_e( 'List all bookings', 'wp-bnb' ); ?></td></tr>
|
||||
<tr><td>GET</td><td><code>/bookings/{id}</code></td><td><?php esc_html_e( 'Get booking details', 'wp-bnb' ); ?></td></tr>
|
||||
<tr><td>PATCH</td><td><code>/bookings/{id}</code></td><td><?php esc_html_e( 'Update booking', 'wp-bnb' ); ?></td></tr>
|
||||
<tr><td>DELETE</td><td><code>/bookings/{id}</code></td><td><?php esc_html_e( 'Cancel booking', 'wp-bnb' ); ?></td></tr>
|
||||
<tr><td>POST</td><td><code>/bookings/{id}/confirm</code></td><td><?php esc_html_e( 'Confirm booking', 'wp-bnb' ); ?></td></tr>
|
||||
<tr><td>POST</td><td><code>/bookings/{id}/check-in</code></td><td><?php esc_html_e( 'Check in guest', 'wp-bnb' ); ?></td></tr>
|
||||
<tr><td>POST</td><td><code>/bookings/{id}/check-out</code></td><td><?php esc_html_e( 'Check out guest', 'wp-bnb' ); ?></td></tr>
|
||||
<tr><td>GET</td><td><code>/guests</code></td><td><?php esc_html_e( 'List guests', 'wp-bnb' ); ?></td></tr>
|
||||
<tr><td>GET</td><td><code>/guests/{id}</code></td><td><?php esc_html_e( 'Get guest details', 'wp-bnb' ); ?></td></tr>
|
||||
<tr><td>GET</td><td><code>/guests/search</code></td><td><?php esc_html_e( 'Search guests', 'wp-bnb' ); ?></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</table>
|
||||
|
||||
<h2 style="margin-top: 30px;"><?php esc_html_e( 'Authentication', 'wp-bnb' ); ?></h2>
|
||||
<p><?php esc_html_e( 'Admin endpoints require authentication. Use one of the following methods:', 'wp-bnb' ); ?></p>
|
||||
<ul style="list-style: disc; margin-left: 20px;">
|
||||
<li><strong><?php esc_html_e( 'Application Passwords:', 'wp-bnb' ); ?></strong> <?php esc_html_e( 'Create one in Users > Your Profile. Use Basic Auth with username and app password.', 'wp-bnb' ); ?></li>
|
||||
<li><strong><?php esc_html_e( 'Cookie + Nonce:', 'wp-bnb' ); ?></strong> <?php esc_html_e( 'For same-domain requests. Pass nonce in X-WP-Nonce header.', 'wp-bnb' ); ?></li>
|
||||
</ul>
|
||||
<h2 style="margin-top: 30px;"><?php esc_html_e( 'API Information', 'wp-bnb' ); ?></h2>
|
||||
|
||||
<h2 style="margin-top: 30px;"><?php esc_html_e( 'Rate Limits', 'wp-bnb' ); ?></h2>
|
||||
<table class="widefat" style="margin-bottom: 20px;">
|
||||
<thead>
|
||||
<table class="form-table">
|
||||
<tr>
|
||||
<th><?php esc_html_e( 'Type', 'wp-bnb' ); ?></th>
|
||||
<th><?php esc_html_e( 'Limit', 'wp-bnb' ); ?></th>
|
||||
<th><?php esc_html_e( 'Applies To', 'wp-bnb' ); ?></th>
|
||||
<th scope="row"><?php esc_html_e( 'Base URL', 'wp-bnb' ); ?></th>
|
||||
<td>
|
||||
<code><?php echo esc_html( $api_base_url ); ?></code>
|
||||
<p class="description">
|
||||
<?php esc_html_e( 'All API endpoints are prefixed with this URL.', 'wp-bnb' ); ?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td><?php esc_html_e( 'Public', 'wp-bnb' ); ?></td><td>60/min</td><td><?php esc_html_e( 'GET rooms, buildings, services', 'wp-bnb' ); ?></td></tr>
|
||||
<tr><td><?php esc_html_e( 'Availability', 'wp-bnb' ); ?></td><td>30/min</td><td><?php esc_html_e( 'Availability checks, calendar', 'wp-bnb' ); ?></td></tr>
|
||||
<tr><td><?php esc_html_e( 'Booking', 'wp-bnb' ); ?></td><td>10/min</td><td><?php esc_html_e( 'Booking creation', 'wp-bnb' ); ?></td></tr>
|
||||
<tr><td><?php esc_html_e( 'Admin', 'wp-bnb' ); ?></td><td>120/min</td><td><?php esc_html_e( 'All admin endpoints', 'wp-bnb' ); ?></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e( 'API Version', 'wp-bnb' ); ?></th>
|
||||
<td>
|
||||
<code><?php echo esc_html( RestApi::VERSION ); ?></code>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e( 'Info Endpoint', 'wp-bnb' ); ?></th>
|
||||
<td>
|
||||
<code><?php echo esc_html( $api_base_url . '/info' ); ?></code>
|
||||
<p class="description">
|
||||
<?php esc_html_e( 'Returns API information and available endpoints.', 'wp-bnb' ); ?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p class="submit">
|
||||
<?php submit_button( __( 'Save API Settings', 'wp-bnb' ), 'primary', 'submit', false ); ?>
|
||||
</p>
|
||||
<?php submit_button( __( 'Save Settings', 'wp-bnb' ) ); ?>
|
||||
|
||||
<?php elseif ( 'rate-limits' === $active_subtab ) : ?>
|
||||
<!-- Rate Limits Subtab -->
|
||||
<h2><?php esc_html_e( 'Rate Limit Configuration', 'wp-bnb' ); ?></h2>
|
||||
|
||||
<?php if ( 'yes' !== $rate_limiting ) : ?>
|
||||
<div class="notice notice-warning inline" style="margin: 15px 0;">
|
||||
<p>
|
||||
<?php esc_html_e( 'Rate limiting is currently disabled.', 'wp-bnb' ); ?>
|
||||
<a href="<?php echo esc_url( $base_url . '&subtab=general' ); ?>"><?php esc_html_e( 'Enable it in General settings', 'wp-bnb' ); ?></a>
|
||||
</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<p class="description"><?php esc_html_e( 'Configure the number of requests allowed per time window for each endpoint type.', 'wp-bnb' ); ?></p>
|
||||
|
||||
<table class="form-table">
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e( 'Time Window', 'wp-bnb' ); ?></th>
|
||||
<td>
|
||||
<input type="number" name="wp_bnb_rate_limit_window" value="<?php echo esc_attr( $limit_window ); ?>" min="10" max="300" step="10" class="small-text">
|
||||
<?php esc_html_e( 'seconds', 'wp-bnb' ); ?>
|
||||
<p class="description">
|
||||
<?php esc_html_e( 'The time window for rate limit counting. Default: 60 seconds.', 'wp-bnb' ); ?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e( 'Public Endpoints', 'wp-bnb' ); ?></th>
|
||||
<td>
|
||||
<input type="number" name="wp_bnb_rate_limit_public" value="<?php echo esc_attr( $limit_public ); ?>" min="1" max="1000" class="small-text">
|
||||
<?php esc_html_e( 'requests per window', 'wp-bnb' ); ?>
|
||||
<p class="description">
|
||||
<?php
|
||||
printf(
|
||||
/* translators: %d: default limit */
|
||||
esc_html__( 'Limit for public read endpoints (rooms, buildings, services). Default: %d', 'wp-bnb' ),
|
||||
$defaults['public']
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e( 'Availability Endpoints', 'wp-bnb' ); ?></th>
|
||||
<td>
|
||||
<input type="number" name="wp_bnb_rate_limit_availability" value="<?php echo esc_attr( $limit_avail ); ?>" min="1" max="1000" class="small-text">
|
||||
<?php esc_html_e( 'requests per window', 'wp-bnb' ); ?>
|
||||
<p class="description">
|
||||
<?php
|
||||
printf(
|
||||
/* translators: %d: default limit */
|
||||
esc_html__( 'Limit for availability checks and calendar requests. Default: %d', 'wp-bnb' ),
|
||||
$defaults['availability']
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e( 'Booking Endpoints', 'wp-bnb' ); ?></th>
|
||||
<td>
|
||||
<input type="number" name="wp_bnb_rate_limit_booking" value="<?php echo esc_attr( $limit_booking ); ?>" min="1" max="100" class="small-text">
|
||||
<?php esc_html_e( 'requests per window', 'wp-bnb' ); ?>
|
||||
<p class="description">
|
||||
<?php
|
||||
printf(
|
||||
/* translators: %d: default limit */
|
||||
esc_html__( 'Limit for booking creation. Keep low to prevent abuse. Default: %d', 'wp-bnb' ),
|
||||
$defaults['booking']
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e( 'Admin Endpoints', 'wp-bnb' ); ?></th>
|
||||
<td>
|
||||
<input type="number" name="wp_bnb_rate_limit_admin" value="<?php echo esc_attr( $limit_admin ); ?>" min="1" max="1000" class="small-text">
|
||||
<?php esc_html_e( 'requests per window', 'wp-bnb' ); ?>
|
||||
<p class="description">
|
||||
<?php
|
||||
printf(
|
||||
/* translators: %d: default limit */
|
||||
esc_html__( 'Limit for authenticated admin endpoints. Default: %d', 'wp-bnb' ),
|
||||
$defaults['admin']
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2 style="margin-top: 30px;"><?php esc_html_e( 'Current Rate Limits Summary', 'wp-bnb' ); ?></h2>
|
||||
<table class="widefat striped" style="max-width: 600px;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php esc_html_e( 'Type', 'wp-bnb' ); ?></th>
|
||||
<th><?php esc_html_e( 'Limit', 'wp-bnb' ); ?></th>
|
||||
<th><?php esc_html_e( 'Applies To', 'wp-bnb' ); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><?php esc_html_e( 'Public', 'wp-bnb' ); ?></td>
|
||||
<td><strong><?php echo esc_html( $limit_public . '/' . $limit_window . 's' ); ?></strong></td>
|
||||
<td><?php esc_html_e( 'GET rooms, buildings, services', 'wp-bnb' ); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php esc_html_e( 'Availability', 'wp-bnb' ); ?></td>
|
||||
<td><strong><?php echo esc_html( $limit_avail . '/' . $limit_window . 's' ); ?></strong></td>
|
||||
<td><?php esc_html_e( 'Availability checks, calendar', 'wp-bnb' ); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php esc_html_e( 'Booking', 'wp-bnb' ); ?></td>
|
||||
<td><strong><?php echo esc_html( $limit_booking . '/' . $limit_window . 's' ); ?></strong></td>
|
||||
<td><?php esc_html_e( 'Booking creation', 'wp-bnb' ); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php esc_html_e( 'Admin', 'wp-bnb' ); ?></td>
|
||||
<td><strong><?php echo esc_html( $limit_admin . '/' . $limit_window . 's' ); ?></strong></td>
|
||||
<td><?php esc_html_e( 'All admin endpoints', 'wp-bnb' ); ?></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<?php submit_button( __( 'Save Rate Limits', 'wp-bnb' ) ); ?>
|
||||
|
||||
<?php else : ?>
|
||||
<!-- Endpoints Subtab -->
|
||||
<h2><?php esc_html_e( 'Available Endpoints', 'wp-bnb' ); ?></h2>
|
||||
|
||||
<h3><?php esc_html_e( 'Public Endpoints', 'wp-bnb' ); ?></h3>
|
||||
<p class="description"><?php esc_html_e( 'These endpoints are accessible without authentication.', 'wp-bnb' ); ?></p>
|
||||
<table class="widefat striped" style="margin-bottom: 20px;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 80px;"><?php esc_html_e( 'Method', 'wp-bnb' ); ?></th>
|
||||
<th style="width: 250px;"><?php esc_html_e( 'Endpoint', 'wp-bnb' ); ?></th>
|
||||
<th><?php esc_html_e( 'Description', 'wp-bnb' ); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td><span class="wp-bnb-method get">GET</span></td><td><code>/buildings</code></td><td><?php esc_html_e( 'List all buildings', 'wp-bnb' ); ?></td></tr>
|
||||
<tr><td><span class="wp-bnb-method get">GET</span></td><td><code>/buildings/{id}</code></td><td><?php esc_html_e( 'Get building details', 'wp-bnb' ); ?></td></tr>
|
||||
<tr><td><span class="wp-bnb-method get">GET</span></td><td><code>/buildings/{id}/rooms</code></td><td><?php esc_html_e( 'List rooms in building', 'wp-bnb' ); ?></td></tr>
|
||||
<tr><td><span class="wp-bnb-method get">GET</span></td><td><code>/rooms</code></td><td><?php esc_html_e( 'List/search rooms', 'wp-bnb' ); ?></td></tr>
|
||||
<tr><td><span class="wp-bnb-method get">GET</span></td><td><code>/rooms/{id}</code></td><td><?php esc_html_e( 'Get room details', 'wp-bnb' ); ?></td></tr>
|
||||
<tr><td><span class="wp-bnb-method get">GET</span></td><td><code>/rooms/{id}/availability</code></td><td><?php esc_html_e( 'Check room availability', 'wp-bnb' ); ?></td></tr>
|
||||
<tr><td><span class="wp-bnb-method get">GET</span></td><td><code>/rooms/{id}/calendar</code></td><td><?php esc_html_e( 'Get room calendar', 'wp-bnb' ); ?></td></tr>
|
||||
<tr><td><span class="wp-bnb-method post">POST</span></td><td><code>/availability/search</code></td><td><?php esc_html_e( 'Search available rooms', 'wp-bnb' ); ?></td></tr>
|
||||
<tr><td><span class="wp-bnb-method get">GET</span></td><td><code>/services</code></td><td><?php esc_html_e( 'List services', 'wp-bnb' ); ?></td></tr>
|
||||
<tr><td><span class="wp-bnb-method post">POST</span></td><td><code>/pricing/calculate</code></td><td><?php esc_html_e( 'Calculate booking price', 'wp-bnb' ); ?></td></tr>
|
||||
<tr><td><span class="wp-bnb-method post">POST</span></td><td><code>/bookings</code></td><td><?php esc_html_e( 'Create booking (pending status)', 'wp-bnb' ); ?></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h3><?php esc_html_e( 'Admin Endpoints', 'wp-bnb' ); ?></h3>
|
||||
<p class="description"><?php esc_html_e( 'These endpoints require authentication (Application Password or Cookie + Nonce).', 'wp-bnb' ); ?></p>
|
||||
<table class="widefat striped" style="margin-bottom: 20px;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 80px;"><?php esc_html_e( 'Method', 'wp-bnb' ); ?></th>
|
||||
<th style="width: 250px;"><?php esc_html_e( 'Endpoint', 'wp-bnb' ); ?></th>
|
||||
<th><?php esc_html_e( 'Description', 'wp-bnb' ); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td><span class="wp-bnb-method get">GET</span></td><td><code>/bookings</code></td><td><?php esc_html_e( 'List all bookings', 'wp-bnb' ); ?></td></tr>
|
||||
<tr><td><span class="wp-bnb-method get">GET</span></td><td><code>/bookings/{id}</code></td><td><?php esc_html_e( 'Get booking details', 'wp-bnb' ); ?></td></tr>
|
||||
<tr><td><span class="wp-bnb-method patch">PATCH</span></td><td><code>/bookings/{id}</code></td><td><?php esc_html_e( 'Update booking', 'wp-bnb' ); ?></td></tr>
|
||||
<tr><td><span class="wp-bnb-method delete">DELETE</span></td><td><code>/bookings/{id}</code></td><td><?php esc_html_e( 'Cancel booking', 'wp-bnb' ); ?></td></tr>
|
||||
<tr><td><span class="wp-bnb-method post">POST</span></td><td><code>/bookings/{id}/confirm</code></td><td><?php esc_html_e( 'Confirm booking', 'wp-bnb' ); ?></td></tr>
|
||||
<tr><td><span class="wp-bnb-method post">POST</span></td><td><code>/bookings/{id}/check-in</code></td><td><?php esc_html_e( 'Check in guest', 'wp-bnb' ); ?></td></tr>
|
||||
<tr><td><span class="wp-bnb-method post">POST</span></td><td><code>/bookings/{id}/check-out</code></td><td><?php esc_html_e( 'Check out guest', 'wp-bnb' ); ?></td></tr>
|
||||
<tr><td><span class="wp-bnb-method get">GET</span></td><td><code>/guests</code></td><td><?php esc_html_e( 'List guests', 'wp-bnb' ); ?></td></tr>
|
||||
<tr><td><span class="wp-bnb-method get">GET</span></td><td><code>/guests/{id}</code></td><td><?php esc_html_e( 'Get guest details', 'wp-bnb' ); ?></td></tr>
|
||||
<tr><td><span class="wp-bnb-method get">GET</span></td><td><code>/guests/search</code></td><td><?php esc_html_e( 'Search guests', 'wp-bnb' ); ?></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h2 style="margin-top: 30px;"><?php esc_html_e( 'Authentication', 'wp-bnb' ); ?></h2>
|
||||
<p><?php esc_html_e( 'Admin endpoints require authentication. Use one of the following methods:', 'wp-bnb' ); ?></p>
|
||||
|
||||
<table class="form-table">
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<span class="dashicons dashicons-admin-network" style="color: #2271b1;"></span>
|
||||
<?php esc_html_e( 'Application Passwords', 'wp-bnb' ); ?>
|
||||
</th>
|
||||
<td>
|
||||
<p><?php esc_html_e( 'Create an Application Password in Users > Your Profile.', 'wp-bnb' ); ?></p>
|
||||
<p><code>Authorization: Basic base64(username:app-password)</code></p>
|
||||
<p class="description"><?php esc_html_e( 'Recommended for external applications and integrations.', 'wp-bnb' ); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<span class="dashicons dashicons-lock" style="color: #2271b1;"></span>
|
||||
<?php esc_html_e( 'Cookie + Nonce', 'wp-bnb' ); ?>
|
||||
</th>
|
||||
<td>
|
||||
<p><?php esc_html_e( 'For same-domain JavaScript requests when user is logged in.', 'wp-bnb' ); ?></p>
|
||||
<p><code>X-WP-Nonce: <?php echo esc_html( wp_create_nonce( 'wp_rest' ) ); ?></code></p>
|
||||
<p class="description"><?php esc_html_e( 'Best for frontend JavaScript that interacts with the API.', 'wp-bnb' ); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<?php endif; ?>
|
||||
</form>
|
||||
<?php
|
||||
}
|
||||
@@ -1836,6 +2008,31 @@ final class Plugin {
|
||||
update_option( 'wp_bnb_api_enabled', $api_enabled );
|
||||
update_option( 'wp_bnb_api_rate_limiting', $rate_limiting );
|
||||
|
||||
// Save rate limit configuration.
|
||||
$defaults = \Magdev\WpBnb\Api\RateLimiter::get_default_limits();
|
||||
|
||||
$limit_window = isset( $_POST['wp_bnb_rate_limit_window'] )
|
||||
? max( 10, min( 300, absint( $_POST['wp_bnb_rate_limit_window'] ) ) )
|
||||
: 60;
|
||||
$limit_public = isset( $_POST['wp_bnb_rate_limit_public'] )
|
||||
? max( 1, min( 1000, absint( $_POST['wp_bnb_rate_limit_public'] ) ) )
|
||||
: $defaults['public'];
|
||||
$limit_avail = isset( $_POST['wp_bnb_rate_limit_availability'] )
|
||||
? max( 1, min( 1000, absint( $_POST['wp_bnb_rate_limit_availability'] ) ) )
|
||||
: $defaults['availability'];
|
||||
$limit_booking = isset( $_POST['wp_bnb_rate_limit_booking'] )
|
||||
? max( 1, min( 100, absint( $_POST['wp_bnb_rate_limit_booking'] ) ) )
|
||||
: $defaults['booking'];
|
||||
$limit_admin = isset( $_POST['wp_bnb_rate_limit_admin'] )
|
||||
? max( 1, min( 1000, absint( $_POST['wp_bnb_rate_limit_admin'] ) ) )
|
||||
: $defaults['admin'];
|
||||
|
||||
update_option( 'wp_bnb_rate_limit_window', $limit_window );
|
||||
update_option( 'wp_bnb_rate_limit_public', $limit_public );
|
||||
update_option( 'wp_bnb_rate_limit_availability', $limit_avail );
|
||||
update_option( 'wp_bnb_rate_limit_booking', $limit_booking );
|
||||
update_option( 'wp_bnb_rate_limit_admin', $limit_admin );
|
||||
|
||||
add_settings_error( 'wp_bnb_settings', 'settings_saved', __( 'API settings saved.', 'wp-bnb' ), 'success' );
|
||||
settings_errors( 'wp_bnb_settings' );
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user