From 9bef5994062b71981e4cd944fefaa8353f8e9a87 Mon Sep 17 00:00:00 2001 From: jknapp Date: Wed, 13 Aug 2025 13:50:56 -0700 Subject: [PATCH] Fix frontend shortcode AJAX nonce validation issues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Added verify_ajax_nonce() helper method to check both admin and frontend nonces - Updated ajax_generate_capability_token() to accept frontend nonce - Updated ajax_get_phone_numbers() to accept frontend nonce - Updated ajax_get_waiting_calls() to accept frontend nonce - Updated ajax_accept_next_queue_call() to accept frontend nonce - Resolves 403 AJAX errors when using shortcode on frontend The shortcode creates 'twp_frontend_nonce' while admin uses 'twp_ajax_nonce' Now both are accepted by the AJAX handlers for proper frontend functionality 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- admin/class-twp-admin.php | 41 +++++++++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/admin/class-twp-admin.php b/admin/class-twp-admin.php index ef6f093..a79d331 100644 --- a/admin/class-twp-admin.php +++ b/admin/class-twp-admin.php @@ -15,6 +15,23 @@ class TWP_Admin { $this->version = $version; } + /** + * Verify AJAX nonce - checks both admin and frontend nonces + */ + private function verify_ajax_nonce() { + // Try admin nonce first + if (wp_verify_nonce($_POST['nonce'] ?? '', 'twp_ajax_nonce')) { + return true; + } + + // Try frontend nonce + if (wp_verify_nonce($_POST['nonce'] ?? '', 'twp_frontend_nonce')) { + return true; + } + + return false; + } + /** * Register admin menu */ @@ -3088,7 +3105,11 @@ class TWP_Admin { * AJAX handler for getting phone numbers */ public function ajax_get_phone_numbers() { - check_ajax_referer('twp_ajax_nonce', 'nonce'); + // Check for either admin or frontend nonce + if (!$this->verify_ajax_nonce()) { + wp_send_json_error('Invalid nonce'); + return; + } if (!current_user_can('manage_options') && !current_user_can('twp_access_phone_numbers')) { wp_send_json_error('Unauthorized - Phone number access required'); @@ -3873,7 +3894,11 @@ class TWP_Admin { * AJAX handler for accepting next call from a queue */ public function ajax_accept_next_queue_call() { - check_ajax_referer('twp_ajax_nonce', 'nonce'); + // Check for either admin or frontend nonce + if (!$this->verify_ajax_nonce()) { + wp_send_json_error('Invalid nonce'); + return; + } $queue_id = intval($_POST['queue_id']); $user_id = get_current_user_id(); @@ -3922,7 +3947,11 @@ class TWP_Admin { * AJAX handler for getting waiting calls */ public function ajax_get_waiting_calls() { - check_ajax_referer('twp_ajax_nonce', 'nonce'); + // Check for either admin or frontend nonce + if (!$this->verify_ajax_nonce()) { + wp_send_json_error('Invalid nonce'); + return; + } global $wpdb; $calls_table = $wpdb->prefix . 'twp_queued_calls'; @@ -4121,7 +4150,11 @@ class TWP_Admin { * AJAX handler for generating capability tokens for Browser Phone */ public function ajax_generate_capability_token() { - check_ajax_referer('twp_ajax_nonce', 'nonce'); + // Check for either admin or frontend nonce + if (!$this->verify_ajax_nonce()) { + wp_send_json_error('Invalid nonce'); + return; + } if (!current_user_can('manage_options') && !current_user_can('twp_access_browser_phone')) { wp_send_json_error('Insufficient permissions');