Add Site Metadata Endpoint and API Key Management
- Introduced a new Site Metadata endpoint (`GET /wp-json/igny8/v1/site-metadata/`) for retrieving available post types and taxonomies, including counts. - Added API key input in the admin settings for authentication, with secure storage and revocation functionality. - Implemented a toggle for enabling/disabling two-way sync operations. - Updated documentation to reflect new features and usage examples. - Enhanced permission checks for REST API calls to ensure secure access.
This commit is contained in:
@@ -64,6 +64,11 @@ class Igny8Admin {
|
||||
public function register_settings() {
|
||||
register_setting('igny8_settings', 'igny8_email');
|
||||
register_setting('igny8_settings', 'igny8_site_id');
|
||||
register_setting('igny8_settings', 'igny8_enable_two_way_sync', array(
|
||||
'type' => 'boolean',
|
||||
'sanitize_callback' => array($this, 'sanitize_boolean'),
|
||||
'default' => 1
|
||||
));
|
||||
|
||||
register_setting('igny8_bridge_connection', 'igny8_connection_enabled', array(
|
||||
'type' => 'boolean',
|
||||
@@ -161,6 +166,17 @@ class Igny8Admin {
|
||||
$this->handle_connection();
|
||||
}
|
||||
|
||||
// Handle revoke API key
|
||||
if (isset($_POST['igny8_revoke_api_key']) && check_admin_referer('igny8_revoke_api_key')) {
|
||||
self::revoke_api_key();
|
||||
add_settings_error(
|
||||
'igny8_settings',
|
||||
'igny8_api_key_revoked',
|
||||
__('API key revoked and removed from this site.', 'igny8-bridge'),
|
||||
'updated'
|
||||
);
|
||||
}
|
||||
|
||||
// Handle webhook secret regeneration
|
||||
if (isset($_POST['igny8_regenerate_secret']) && check_admin_referer('igny8_regenerate_secret')) {
|
||||
$new_secret = igny8_regenerate_webhook_secret();
|
||||
@@ -182,43 +198,78 @@ class Igny8Admin {
|
||||
private function handle_connection() {
|
||||
$email = sanitize_email($_POST['igny8_email'] ?? '');
|
||||
$password = $_POST['igny8_password'] ?? '';
|
||||
|
||||
if (empty($email) || empty($password)) {
|
||||
$api_key = sanitize_text_field($_POST['igny8_api_key'] ?? '');
|
||||
|
||||
// Require email, password AND API key per updated policy
|
||||
if (empty($email) || empty($password) || empty($api_key)) {
|
||||
add_settings_error(
|
||||
'igny8_settings',
|
||||
'igny8_error',
|
||||
__('Email and password are required.', 'igny8-bridge'),
|
||||
__('Email, password and API key are all required to establish the connection.', 'igny8-bridge'),
|
||||
'error'
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// First, attempt login with email/password
|
||||
$api = new Igny8API();
|
||||
|
||||
if ($api->login($email, $password)) {
|
||||
update_option('igny8_email', $email);
|
||||
|
||||
// Try to get site ID (if available)
|
||||
$site_response = $api->get('/system/sites/');
|
||||
if ($site_response['success'] && !empty($site_response['results'])) {
|
||||
$site = $site_response['results'][0];
|
||||
update_option('igny8_site_id', $site['id']);
|
||||
}
|
||||
|
||||
add_settings_error(
|
||||
'igny8_settings',
|
||||
'igny8_connected',
|
||||
__('Successfully connected to IGNY8 API.', 'igny8-bridge'),
|
||||
'updated'
|
||||
);
|
||||
} else {
|
||||
|
||||
if (!$api->login($email, $password)) {
|
||||
add_settings_error(
|
||||
'igny8_settings',
|
||||
'igny8_error',
|
||||
__('Failed to connect to IGNY8 API. Please check your credentials.', 'igny8-bridge'),
|
||||
__('Failed to connect to IGNY8 API with provided credentials.', 'igny8-bridge'),
|
||||
'error'
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Store email
|
||||
update_option('igny8_email', $email);
|
||||
|
||||
// Store API key securely and also set access token to the API key for subsequent calls if desired
|
||||
if (function_exists('igny8_store_secure_option')) {
|
||||
igny8_store_secure_option('igny8_api_key', $api_key);
|
||||
igny8_store_secure_option('igny8_access_token', $api_key);
|
||||
} else {
|
||||
update_option('igny8_api_key', $api_key);
|
||||
update_option('igny8_access_token', $api_key);
|
||||
}
|
||||
|
||||
// Try to get site ID (if available) using the authenticated client
|
||||
$site_response = $api->get('/system/sites/');
|
||||
if ($site_response['success'] && !empty($site_response['results'])) {
|
||||
$site = $site_response['results'][0];
|
||||
update_option('igny8_site_id', $site['id']);
|
||||
}
|
||||
|
||||
add_settings_error(
|
||||
'igny8_settings',
|
||||
'igny8_connected',
|
||||
__('Successfully connected to IGNY8 API and stored API key.', 'igny8-bridge'),
|
||||
'updated'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Revoke stored API key (secure delete)
|
||||
*
|
||||
* Public so tests can call it directly.
|
||||
*/
|
||||
public static function revoke_api_key() {
|
||||
if (function_exists('igny8_delete_secure_option')) {
|
||||
igny8_delete_secure_option('igny8_api_key');
|
||||
igny8_delete_secure_option('igny8_access_token');
|
||||
igny8_delete_secure_option('igny8_refresh_token');
|
||||
} else {
|
||||
delete_option('igny8_api_key');
|
||||
delete_option('igny8_access_token');
|
||||
delete_option('igny8_refresh_token');
|
||||
}
|
||||
|
||||
// Also clear token-issued timestamps
|
||||
delete_option('igny8_token_refreshed_at');
|
||||
delete_option('igny8_access_token_issued');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,6 +15,7 @@ $email = get_option('igny8_email', '');
|
||||
$site_id = get_option('igny8_site_id', '');
|
||||
$access_token = function_exists('igny8_get_secure_option') ? igny8_get_secure_option('igny8_access_token') : get_option('igny8_access_token');
|
||||
$is_connected = !empty($access_token);
|
||||
$api_key = function_exists('igny8_get_secure_option') ? igny8_get_secure_option('igny8_api_key') : get_option('igny8_api_key');
|
||||
$date_format = get_option('date_format');
|
||||
$time_format = get_option('time_format');
|
||||
$now = current_time('timestamp');
|
||||
@@ -53,6 +54,7 @@ $pending_links = array_filter($link_queue, function($item) {
|
||||
return $item['status'] === 'pending';
|
||||
});
|
||||
$webhook_logs = igny8_get_webhook_logs(array('limit' => 10));
|
||||
$two_way_sync = (int) get_option('igny8_enable_two_way_sync', 1);
|
||||
|
||||
?>
|
||||
|
||||
@@ -60,6 +62,13 @@ $webhook_logs = igny8_get_webhook_logs(array('limit' => 10));
|
||||
<h1><?php echo esc_html(get_admin_page_title()); ?></h1>
|
||||
|
||||
<?php settings_errors('igny8_settings'); ?>
|
||||
<div class="notice notice-info inline" style="margin-top:10px;">
|
||||
<p>
|
||||
<strong><?php _e('Integration modes explained:', 'igny8-bridge'); ?></strong><br />
|
||||
<?php _e('• Enable Sync Operations: controls whether background and manual sync actions occur (cron jobs, webhooks, sync buttons).', 'igny8-bridge'); ?><br />
|
||||
<?php _e('• Enable Two-Way Sync: controls whether bi-directional syncing (IGNY8 → WordPress and WordPress → IGNY8) is permitted. Disabling this will suppress sync actions but API endpoints remain accessible for discovery and diagnostics.', 'igny8-bridge'); ?>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="igny8-settings-container">
|
||||
<div class="igny8-settings-card">
|
||||
@@ -87,6 +96,32 @@ $webhook_logs = igny8_get_webhook_logs(array('limit' => 10));
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="igny8_api_key"><?php _e('API Key', 'igny8-bridge'); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<input
|
||||
type="password"
|
||||
id="igny8_api_key"
|
||||
name="igny8_api_key"
|
||||
value="<?php echo esc_attr($api_key ? '********' : ''); ?>"
|
||||
class="regular-text"
|
||||
placeholder="<?php _e('Paste your IGNY8 API key here (optional)', 'igny8-bridge'); ?>"
|
||||
/>
|
||||
<p class="description">
|
||||
<?php _e('If you have an API key from the IGNY8 SaaS app, paste it here to authenticate the bridge. Leave blank to use email/password.', 'igny8-bridge'); ?>
|
||||
</p>
|
||||
<?php if ($api_key) : ?>
|
||||
<form method="post" action="" style="display:inline-block; margin-left:10px;">
|
||||
<?php wp_nonce_field('igny8_revoke_api_key'); ?>
|
||||
<button type="submit" name="igny8_revoke_api_key" class="button button-secondary" onclick="return confirm('<?php _e('Revoke stored API key? This will remove the key from this site.', 'igny8-bridge'); ?>');">
|
||||
<?php _e('Revoke API Key', 'igny8-bridge'); ?>
|
||||
</button>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="igny8_password"><?php _e('Password', 'igny8-bridge'); ?></label>
|
||||
@@ -152,6 +187,23 @@ $webhook_logs = igny8_get_webhook_logs(array('limit' => 10));
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="igny8_enable_two_way_sync"><?php _e('Enable Two-Way Sync', 'igny8-bridge'); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
id="igny8_enable_two_way_sync"
|
||||
name="igny8_enable_two_way_sync"
|
||||
value="1"
|
||||
<?php checked($two_way_sync, 1); ?>
|
||||
/>
|
||||
<?php _e('Allow bi-directional sync (IGNY8 ↔ WordPress). When disabled, outbound/inbound sync actions are suppressed but API endpoints remain accessible.', 'igny8-bridge'); ?>
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
<?php if ($email) : ?>
|
||||
<tr>
|
||||
<th scope="row"><?php _e('Email', 'igny8-bridge'); ?></th>
|
||||
|
||||
Reference in New Issue
Block a user