Refactor IGNY8 Bridge to use API key authentication exclusively
- Removed email/password authentication and related settings from the plugin. - Updated API connection logic to utilize only the API key for authentication. - Simplified the admin interface by removing webhook-related settings and messages. - Enhanced the settings page with improved UI and status indicators for API connection. - Added a new REST API endpoint to check plugin status and connection health. - Updated styles for a modernized look and feel across the admin interface.
This commit is contained in:
@@ -26,41 +26,31 @@ class Igny8API {
|
||||
private $base_url = 'https://api.igny8.com/api/v1';
|
||||
|
||||
/**
|
||||
* Access token
|
||||
* API key (used as access token)
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
private $access_token = null;
|
||||
|
||||
/**
|
||||
* Whether authentication is via API key (true) or tokens (false)
|
||||
* Whether authentication is via API key (always true now)
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $api_key_auth = false;
|
||||
|
||||
/**
|
||||
* Refresh token
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
private $refresh_token = null;
|
||||
private $api_key_auth = true;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Only uses API key for authentication
|
||||
*/
|
||||
public function __construct() {
|
||||
if (function_exists('igny8_get_secure_option')) {
|
||||
$this->access_token = igny8_get_secure_option('igny8_access_token');
|
||||
$this->refresh_token = igny8_get_secure_option('igny8_refresh_token');
|
||||
$api_key = igny8_get_secure_option('igny8_api_key');
|
||||
} else {
|
||||
$this->access_token = get_option('igny8_access_token');
|
||||
$this->refresh_token = get_option('igny8_refresh_token');
|
||||
$api_key = get_option('igny8_api_key');
|
||||
}
|
||||
|
||||
// If an API key is provided, prefer it as the access token
|
||||
// API key is the only authentication method
|
||||
if (!empty($api_key)) {
|
||||
$this->access_token = $api_key;
|
||||
$this->api_key_auth = true;
|
||||
@@ -68,96 +58,32 @@ class Igny8API {
|
||||
}
|
||||
|
||||
/**
|
||||
* Login and store tokens
|
||||
* Connect using API key
|
||||
*
|
||||
* @param string $email User email
|
||||
* @param string $password User password
|
||||
* @param string $api_key API key from IGNY8 app
|
||||
* @return bool True on success, false on failure
|
||||
*/
|
||||
public function login($email, $password) {
|
||||
$response = wp_remote_post($this->base_url . '/auth/login/', array(
|
||||
'headers' => array(
|
||||
'Content-Type' => 'application/json'
|
||||
),
|
||||
'body' => json_encode(array(
|
||||
'email' => $email,
|
||||
'password' => $password
|
||||
)),
|
||||
'timeout' => 30
|
||||
));
|
||||
|
||||
$body = $this->parse_response($response);
|
||||
|
||||
if ($body['success']) {
|
||||
$this->access_token = $body['data']['access'];
|
||||
$this->refresh_token = $body['data']['refresh'];
|
||||
|
||||
if (function_exists('igny8_store_secure_option')) {
|
||||
igny8_store_secure_option('igny8_access_token', $this->access_token);
|
||||
igny8_store_secure_option('igny8_refresh_token', $this->refresh_token);
|
||||
} else {
|
||||
update_option('igny8_access_token', $this->access_token);
|
||||
update_option('igny8_refresh_token', $this->refresh_token);
|
||||
}
|
||||
update_option('igny8_email', $email);
|
||||
|
||||
// Store token refresh time
|
||||
$timestamp = current_time('timestamp');
|
||||
update_option('igny8_token_refreshed_at', $timestamp);
|
||||
update_option('igny8_access_token_issued', $timestamp);
|
||||
update_option('igny8_last_api_health_check', $timestamp);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh access token
|
||||
*
|
||||
* @return bool True on success, false on failure
|
||||
*/
|
||||
public function refresh_token() {
|
||||
if (!$this->refresh_token) {
|
||||
public function connect($api_key) {
|
||||
if (empty($api_key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$response = wp_remote_post($this->base_url . '/auth/refresh/', array(
|
||||
'headers' => array(
|
||||
'Content-Type' => 'application/json'
|
||||
),
|
||||
'body' => json_encode(array(
|
||||
'refresh' => $this->refresh_token
|
||||
)),
|
||||
'timeout' => 30
|
||||
));
|
||||
// Store API key
|
||||
if (function_exists('igny8_store_secure_option')) {
|
||||
igny8_store_secure_option('igny8_api_key', $api_key);
|
||||
} else {
|
||||
update_option('igny8_api_key', $api_key);
|
||||
}
|
||||
|
||||
$body = $this->parse_response($response);
|
||||
$this->access_token = $api_key;
|
||||
$this->api_key_auth = true;
|
||||
|
||||
if ($body['success']) {
|
||||
$this->access_token = $body['data']['access'];
|
||||
|
||||
// Refresh token may be updated
|
||||
if (isset($body['data']['refresh'])) {
|
||||
$this->refresh_token = $body['data']['refresh'];
|
||||
if (function_exists('igny8_store_secure_option')) {
|
||||
igny8_store_secure_option('igny8_refresh_token', $this->refresh_token);
|
||||
} else {
|
||||
update_option('igny8_refresh_token', $this->refresh_token);
|
||||
}
|
||||
}
|
||||
|
||||
if (function_exists('igny8_store_secure_option')) {
|
||||
igny8_store_secure_option('igny8_access_token', $this->access_token);
|
||||
} else {
|
||||
update_option('igny8_access_token', $this->access_token);
|
||||
}
|
||||
|
||||
// Test connection by making a simple API call
|
||||
$test_response = $this->get('/auth/sites/');
|
||||
|
||||
if ($test_response['success']) {
|
||||
$timestamp = current_time('timestamp');
|
||||
update_option('igny8_token_refreshed_at', $timestamp);
|
||||
update_option('igny8_access_token_issued', $timestamp);
|
||||
|
||||
update_option('igny8_last_api_health_check', $timestamp);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -271,18 +197,8 @@ class Igny8API {
|
||||
|
||||
$body = $this->parse_response($response);
|
||||
|
||||
// Handle 401 - token expired
|
||||
if (!$body['success'] && wp_remote_retrieve_response_code($response) == 401 && !$this->api_key_auth) {
|
||||
// Try to refresh token (only for email/password auth, not API key)
|
||||
if ($this->refresh_token()) {
|
||||
// Retry request
|
||||
$response = wp_remote_get($url, array(
|
||||
'headers' => $this->get_headers(),
|
||||
'timeout' => 30
|
||||
));
|
||||
$body = $this->parse_response($response);
|
||||
}
|
||||
}
|
||||
// API keys don't expire, so no refresh logic needed
|
||||
// If 401, the API key is invalid or revoked
|
||||
|
||||
return $body;
|
||||
}
|
||||
@@ -303,19 +219,7 @@ class Igny8API {
|
||||
|
||||
$body = $this->parse_response($response);
|
||||
|
||||
// Handle 401 - token expired
|
||||
if (!$body['success'] && wp_remote_retrieve_response_code($response) == 401) {
|
||||
// Try to refresh token
|
||||
if ($this->refresh_token()) {
|
||||
// Retry request
|
||||
$response = wp_remote_post($this->base_url . $endpoint, array(
|
||||
'headers' => $this->get_headers(),
|
||||
'body' => json_encode($data),
|
||||
'timeout' => 60
|
||||
));
|
||||
$body = $this->parse_response($response);
|
||||
}
|
||||
}
|
||||
// API keys don't expire, so no refresh logic needed
|
||||
|
||||
return $body;
|
||||
}
|
||||
|
||||
@@ -77,20 +77,23 @@ class Igny8RestAPI {
|
||||
'callback' => array($this, 'get_site_metadata'),
|
||||
'permission_callback' => '__return_true',
|
||||
));
|
||||
|
||||
// Plugin status endpoint - returns connection status and API key info
|
||||
register_rest_route('igny8/v1', '/status', array(
|
||||
'methods' => 'GET',
|
||||
'callback' => array($this, 'get_status'),
|
||||
'permission_callback' => '__return_true', // Public endpoint for health checks
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check API permission
|
||||
* Check API permission - uses API key only
|
||||
*
|
||||
* @param WP_REST_Request $request Request object
|
||||
* @return bool|WP_Error
|
||||
*/
|
||||
public function check_permission($request) {
|
||||
// Do NOT block endpoints when the plugin connection is disabled.
|
||||
// The plugin-side "Enable Sync Operations" option should only stop background sync actions,
|
||||
// but REST discovery endpoints should remain callable. Authentication is still required.
|
||||
|
||||
// Check if authenticated with IGNY8 via stored token OR X-IGNY8-API-KEY header
|
||||
// Check if authenticated with IGNY8 via API key
|
||||
$api = new Igny8API();
|
||||
|
||||
// Accept explicit X-IGNY8-API-KEY header for incoming requests
|
||||
@@ -102,33 +105,24 @@ class Igny8RestAPI {
|
||||
}
|
||||
}
|
||||
|
||||
if (!$api->is_authenticated()) {
|
||||
return new WP_Error(
|
||||
'rest_forbidden',
|
||||
__('IGNY8 API not authenticated', 'igny8-bridge'),
|
||||
array('status' => 401)
|
||||
);
|
||||
}
|
||||
|
||||
// Verify API token from request header
|
||||
// Check Authorization Bearer header
|
||||
$auth_header = $request->get_header('Authorization');
|
||||
|
||||
if ($auth_header) {
|
||||
$token = get_option('igny8_access_token');
|
||||
if ($token && strpos($auth_header, 'Bearer ' . $token) !== false) {
|
||||
$stored_api_key = function_exists('igny8_get_secure_option') ? igny8_get_secure_option('igny8_api_key') : get_option('igny8_api_key');
|
||||
if ($stored_api_key && strpos($auth_header, 'Bearer ' . $stored_api_key) !== false) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Allow if IGNY8 is connected (for internal use)
|
||||
// Allow if API key is configured (for internal use)
|
||||
if ($api->is_authenticated()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return new WP_Error(
|
||||
'rest_forbidden',
|
||||
__('Invalid authentication', 'igny8-bridge'),
|
||||
array('status' => 403)
|
||||
__('IGNY8 API key not authenticated', 'igny8-bridge'),
|
||||
array('status' => 401)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -345,6 +339,30 @@ class Igny8RestAPI {
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /status - Returns plugin connection status and API key info
|
||||
*
|
||||
* @param WP_REST_Request $request
|
||||
* @return WP_REST_Response
|
||||
*/
|
||||
public function get_status($request) {
|
||||
$api = new Igny8API();
|
||||
$api_key = function_exists('igny8_get_secure_option') ? igny8_get_secure_option('igny8_api_key') : get_option('igny8_api_key');
|
||||
$connection_enabled = igny8_is_connection_enabled();
|
||||
|
||||
$data = array(
|
||||
'connected' => !empty($api_key) && $api->is_authenticated(),
|
||||
'has_api_key' => !empty($api_key),
|
||||
'communication_enabled' => $connection_enabled,
|
||||
'plugin_version' => defined('IGNY8_BRIDGE_VERSION') ? IGNY8_BRIDGE_VERSION : '1.0.0',
|
||||
'wordpress_version' => get_bloginfo('version'),
|
||||
'last_health_check' => get_option('igny8_last_api_health_check', 0),
|
||||
'health' => (!empty($api_key) && $connection_enabled) ? 'healthy' : 'not_configured'
|
||||
);
|
||||
|
||||
return $this->build_unified_response(true, $data, 'Plugin status retrieved', null, null, 200);
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /site-metadata/ - returns post types, taxonomies and counts in unified format
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user