events(); } public function events() { add_action( 'wp_ajax_acb_data_truncate', array( $this, 'ACB_message_truncate' ) ); // Issue 2.1: Removed nopriv hook — unauthenticated users must not truncate data. /* Demo check Creation */ add_action( 'wp_ajax_show_user_inputed_data', array( $this, 'ACB_message_creation' ) ); /* Firebase Configuration */ add_action( 'wp_ajax_acb_save_firebase_config', array( $this, 'save_firebase_config' ) ); add_action( 'wp_ajax_acb_test_firebase_connection', array( $this, 'test_firebase_connection' ) ); add_action( 'wp_ajax_acb_firebase_auth', array( $this, 'firebase_auth' ) ); /* User Management */ add_action( 'wp_ajax_acb_get_all_users', array( $this, 'get_all_users' ) ); add_action( 'wp_ajax_acb_get_users', array( $this, 'get_users_with_admin_status' ) ); // Issue 2.2: Removed nopriv hook — user list (PII) must not be exposed to unauthenticated callers. add_action( 'wp_ajax_acb_toggle_user_agent', array( $this, 'toggle_user_agent' ) ); add_action( 'wp_ajax_acb_sync_firebase_users', array( $this, 'sync_firebase_users' ) ); add_action( 'wp_ajax_acb_get_support_settings', array( $this, 'get_support_settings' ) ); add_action( 'wp_ajax_acb_get_widget_settings', array( $this, 'get_widget_settings' ) ); add_action( 'wp_ajax_nopriv_acb_get_widget_settings', array( $this, 'get_widget_settings' ) ); add_action( 'wp_ajax_acb_save_widget_settings', array( $this, 'save_widget_settings' ) ); add_action( 'wp_ajax_acb_save_support_settings', array( $this, 'save_support_settings' ) ); add_action( 'wp_ajax_acb_check_user_admin_status', array( $this, 'check_user_admin_status' ) ); add_action( 'wp_ajax_acb_refresh_nonce', array( $this, 'refresh_nonce' ) ); add_action( 'wp_ajax_nopriv_acb_refresh_nonce', array( $this, 'refresh_nonce' ) ); } /**Chat data truncate */ public function ACB_message_truncate() { if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'acb_nonce' ) ) { wp_send_json_error( [ 'message' => __( 'Security check failed.','admin-chat-box' ) ] ); wp_die(); } $ACB_message_truncate = new ACB_MessageCreation(); $ACB_message_truncate->ACB_message_truncate(); } /**Chat data fetch */ public function ACB_message_creation() { if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'acb_nonce' ) ) { wp_send_json_error( [ 'message' => __( 'Security check failed.','admin-chat-box' ) ] ); wp_die(); } $ACB_message_creation = new ACB_MessageCreation(); $ACB_message_creation->ACB_message_creation(); } /** * Save Firebase configuration - Only for administrators */ public function save_firebase_config() { // Verify nonce if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'acb_nonce' ) ) { wp_send_json_error( [ 'message' => __( 'Security check failed.','admin-chat-box' ) ] ); wp_die(); } // Check user permissions - Only administrators can save Firebase config if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( [ 'message' => __( 'Insufficient permissions.','admin-chat-box' ) ] ); wp_die(); } // Validate POST data exists if ( ! isset( $_POST['config'] ) || empty( $_POST['config'] ) ) { wp_send_json_error( [ 'message' => __( 'Configuration data is required.','admin-chat-box' ) ] ); wp_die(); } // Sanitize and unslash the config data $config = wp_unslash( $_POST['config'] ); $config = sanitize_textarea_field( $config ); $config_array = json_decode( $config, true ); // Check for JSON decode errors if ( json_last_error() !== JSON_ERROR_NONE ) { wp_send_json_error( [ 'message' => __( 'Invalid configuration format.','admin-chat-box' ) ] ); wp_die(); } if ( ! is_array( $config_array ) ) { wp_send_json_error( [ 'message' => __( 'Configuration must be a valid JSON object.','admin-chat-box' ) ] ); wp_die(); } // Validate required fields $required_fields = [ 'apiKey', 'authDomain', 'projectId', 'storageBucket', 'messagingSenderId', 'appId' ]; foreach ( $required_fields as $field ) { if ( ! isset( $config_array[ $field ] ) || '' === trim( $config_array[ $field ] ) ) { wp_send_json_error( [ 'message' => sprintf( __( 'Missing or empty required field: %s','admin-chat-box' ), esc_html( $field ) ) ] ); wp_die(); } } // Sanitize individual fields using allowlist (preserves camelCase keys) $sanitized_config = array(); foreach ( $required_fields as $key ) { if ( isset( $config_array[ $key ] ) ) { $sanitized_config[ $key ] = sanitize_text_field( wp_unslash( $config_array[ $key ] ) ); } } // Validate sanitized config still has required fields foreach ( $required_fields as $field ) { if ( ! isset( $sanitized_config[ $field ] ) || empty( $sanitized_config[ $field ] ) ) { wp_send_json_error( [ 'message' => sprintf( __( 'Invalid data for required field: %s','admin-chat-box' ), esc_html( $field ) ) ] ); wp_die(); } } // Save to WordPress options $saved = update_option( 'firebaseConfig', $sanitized_config ); $saved_config = get_option( 'firebaseConfig', [] ); if ( $saved || $saved_config === $sanitized_config ) { wp_send_json_success( [ 'message' => __( 'Firebase configuration saved successfully.','admin-chat-box' ) ] ); } else { wp_send_json_error( [ 'message' => __( 'Failed to save configuration.','admin-chat-box' ) ] ); } wp_die(); } /** * Test Firebase connection - Only for administrators */ public function test_firebase_connection() { // Verify nonce if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'acb_nonce' ) ) { wp_send_json_error( [ 'message' => __( 'Security check failed.','admin-chat-box' ) ] ); wp_die(); } // Check user permissions - Only administrators can test Firebase connection if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( [ 'message' => __( 'Insufficient permissions.','admin-chat-box' ) ] ); wp_die(); } // Validate POST data exists if ( ! isset( $_POST['config'] ) || empty( $_POST['config'] ) ) { wp_send_json_error( [ 'message' => __( 'Configuration data is required.','admin-chat-box' ) ] ); wp_die(); } // Sanitize and unslash the config data $config = wp_unslash( $_POST['config'] ); $config = sanitize_textarea_field( $config ); $config_array = json_decode( $config, true ); // Check for JSON decode errors if ( json_last_error() !== JSON_ERROR_NONE ) { wp_send_json_error( [ 'message' => __( 'Invalid configuration format.','admin-chat-box' ) ] ); wp_die(); } if ( ! is_array( $config_array ) ) { wp_send_json_error( [ 'message' => __( 'Configuration must be a valid JSON object.','admin-chat-box' ) ] ); wp_die(); } // Validate required fields exist if ( ! isset( $config_array['apiKey'] ) || ! isset( $config_array['projectId'] ) ) { wp_send_json_error( [ 'message' => __( 'Missing required configuration fields (apiKey, projectId).','admin-chat-box' ) ] ); wp_die(); } try { $api_key = sanitize_text_field( $config_array['apiKey'] ); $project_id = sanitize_text_field( $config_array['projectId'] ); if ( empty( $api_key ) || empty( $project_id ) ) { wp_send_json_error( [ 'message' => __( 'Invalid API key or project ID.','admin-chat-box' ) ] ); wp_die(); } $test_url = 'https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=' . rawurlencode( $api_key ); $response = wp_remote_post( $test_url, [ 'body' => wp_json_encode( [ 'email' => 'test@example.com', 'password' => 'testpassword123', 'returnSecureToken' => true, ] ), 'headers' => [ 'Content-Type' => 'application/json' ], 'timeout' => 10, 'sslverify' => true, ] ); if ( is_wp_error( $response ) ) { wp_send_json_error( [ 'message' => __( 'Connection failed: ','admin-chat-box' ) . esc_html( $response->get_error_message() ) ] ); wp_die(); } $response_code = wp_remote_retrieve_response_code( $response ); if ( $response_code >= 200 && $response_code < 500 ) { wp_send_json_success( [ 'message' => __( 'Firebase connection successful! Configuration is valid.','admin-chat-box' ) ] ); } else { wp_send_json_error( [ 'message' => __( 'Firebase connection failed. Response code: ','admin-chat-box' ) . absint( $response_code ) ] ); } } catch ( Exception $e ) { wp_send_json_error( [ 'message' => __( 'Connection test failed: ','admin-chat-box' ) . esc_html( $e->getMessage() ) ] ); } wp_die(); } /** * Handle Firebase user authentication — syncs data for the currently logged-in WP user only. * CVE-2026-8787 fix: removed wp_set_auth_cookie / wp_set_current_user and bound to current user. */ public function firebase_auth() { // Verify nonce. if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'acb_nonce' ) ) { wp_send_json_error( [ 'message' => __( 'Security check failed.','admin-chat-box' ) ] ); wp_die(); } // Validate required POST data. if ( ! isset( $_POST['firebase_uid'] ) || '' === trim( $_POST['firebase_uid'] ) ) { wp_send_json_error( [ 'message' => __( 'Missing required field: firebase_uid','admin-chat-box' ) ] ); wp_die(); } // Sanitize inputs. $firebase_uid = sanitize_text_field( wp_unslash( $_POST['firebase_uid'] ) ); $user_name = isset( $_POST['user_name'] ) ? sanitize_text_field( wp_unslash( $_POST['user_name'] ) ) : ''; $user_email = isset( $_POST['user_email'] ) ? sanitize_email( wp_unslash( $_POST['user_email'] ) ) : ''; $user_avatar = isset( $_POST['user_avatar'] ) ? esc_url_raw( wp_unslash( $_POST['user_avatar'] ) ) : ''; $auth_provider = isset( $_POST['auth_provider'] ) ? sanitize_text_field( wp_unslash( $_POST['auth_provider'] ) ) : 'firebase'; if ( empty( $firebase_uid ) ) { wp_send_json_error( [ 'message' => __( 'Invalid Firebase UID.','admin-chat-box' ) ] ); wp_die(); } // SECURITY: bind to the currently logged-in WordPress user only. $current_wp_user = wp_get_current_user(); if ( 0 === $current_wp_user->ID ) { wp_send_json_error( [ 'message' => __( 'Authentication required.','admin-chat-box' ) ] ); wp_die(); } // Prevent email substitution / account takeover. if ( ! empty( $user_email ) && strtolower( $current_wp_user->user_email ) !== strtolower( $user_email ) ) { wp_send_json_error( [ 'message' => __( 'Email mismatch. You may only sync your own account.','admin-chat-box' ) ] ); wp_die(); } $user_id = $current_wp_user->ID; // Update Firebase UID mapping for the current user only. update_user_meta( $user_id, 'firebase_uid', $firebase_uid ); if ( ! empty( $user_avatar ) ) { update_user_meta( $user_id, 'firebase_avatar', $user_avatar ); } update_user_meta( $user_id, 'auth_provider', $auth_provider ); // Update display name only if explicitly provided and different. if ( ! empty( $user_name ) && $current_wp_user->display_name !== $user_name ) { wp_update_user( [ 'ID' => $user_id, 'display_name' => sanitize_text_field( $user_name ), ] ); } // Sync to chat users table — never issue a WordPress session from this endpoint. $this->add_user_to_chat_table( $firebase_uid, $user_name, $current_wp_user->user_email, $user_avatar, $auth_provider ); wp_send_json_success( [ 'message' => __( 'User data synced successfully.','admin-chat-box' ) ] ); wp_die(); } /** * Get all chat users - Only for administrators */ public function get_all_users() { // Verify nonce if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'acb_nonce' ) ) { wp_send_json_error([ 'message' => __( 'Security check failed.','admin-chat-box' ), ]); } // Check user permissions - Only administrators can view all users if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( [ 'message' => __( 'Insufficient permissions.','admin-chat-box' ) ] ); wp_die(); } global $wpdb; $table_users = $wpdb->prefix . 'acb_users'; // Validate table exists if ( $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table_users ) ) !== $table_users ) { wp_send_json_error( [ 'message' => __( 'Users table does not exist.','admin-chat-box' ) ] ); wp_die(); } // Get all users $users = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}acb_users ORDER BY created_at DESC" ) ); if ( false === $users ) { wp_send_json_error( [ 'message' => __( 'Failed to retrieve users.','admin-chat-box' ) ] ); wp_die(); } $formatted_users = []; foreach ($users as $user) { // Check if user is online (last seen within 2 minutes) $last_seen_time = strtotime($user->last_seen); $is_online = (time() - $last_seen_time) < 120; // 2 minutes $formatted_users[] = [ 'id' => absint($user->id), 'firebase_uid' => esc_html($user->firebase_uid), 'user_name' => esc_html($user->user_name), 'user_email' => esc_html($user->user_email), 'user_avatar' => esc_url($user->user_avatar), 'auth_provider' => esc_html($user->auth_provider), 'is_admin' => (bool) $user->is_admin, 'is_online' => $is_online, 'last_seen' => esc_html($user->last_seen), 'created_at' => esc_html($user->created_at), 'formatted_last_seen' => esc_html( wp_date( 'M d, Y > h:i A', strtotime( $user->last_seen ) ) ) ]; } wp_send_json_success([ 'users' => $formatted_users, 'total' => count($formatted_users) ]); } /** * Toggle user admin status - Only for administrators */ public function toggle_user_agent() { if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'acb_nonce' ) ) { wp_send_json_error( [ 'message' => __( 'Security check failed.','admin-chat-box' ) ] ); wp_die(); } // Check user permissions - Only administrators can change user roles if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( [ 'message' => __( 'Insufficient permissions.','admin-chat-box' ) ] ); wp_die(); } // Validate required fields if ( ! isset( $_POST['user_id'] ) || ! isset( $_POST['new_role'] ) ) { wp_send_json_error( [ 'message' => __( 'Missing required fields.','admin-chat-box' ) ] ); wp_die(); } $user_id = absint( $_POST['user_id'] ); $new_role = sanitize_text_field( wp_unslash( $_POST['new_role'] ) ); if ( $user_id <= 0 ) { wp_send_json_error( [ 'message' => __( 'Invalid user ID.','admin-chat-box' ) ] ); wp_die(); } if ( ! in_array( $new_role, [ 'admin', 'regular' ], true ) ) { wp_send_json_error( [ 'message' => __( 'Invalid role specified.','admin-chat-box' ) ] ); wp_die(); } global $wpdb; $table_users = $wpdb->prefix . 'acb_users'; if ( $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table_users ) ) !== $table_users ) { wp_send_json_error( [ 'message' => __( 'Users table does not exist.','admin-chat-box' ) ] ); wp_die(); } $user = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}acb_users WHERE id = %d", $user_id ) ); if ( ! $user ) { wp_send_json_error( [ 'message' => __( 'User not found.','admin-chat-box' ) ] ); wp_die(); } $is_admin = ( 'admin' === $new_role ) ? 1 : 0; $result = $wpdb->update( $table_users, [ 'is_admin' => $is_admin, 'updated_at' => current_time( 'mysql' ), ], [ 'id' => $user_id ], [ '%d', '%s' ], [ '%d' ] ); if ( false === $result ) { wp_send_json_error( [ 'message' => __( 'Failed to update user role.','admin-chat-box' ) ] ); wp_die(); } wp_send_json_success( [ 'message' => __( 'User role updated successfully.','admin-chat-box' ), 'user_id' => $user_id, 'new_role' => $new_role, ] ); wp_die(); } /** * Get support system settings - Available to all users (read-only) */ public function get_support_settings() { // Verify nonce - Use firebase nonce since it's available to all users if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'acb_nonce' ) ) { wp_send_json_error([ 'message' => __( 'Security check failed.','admin-chat-box' ), ]); wp_die(); } // Issue 2.3: Only logged-in users need to know about support mode. if ( ! is_user_logged_in() ) { wp_send_json_error( [ 'message' => __( 'Authentication required.','admin-chat-box' ) ] ); wp_die(); } $support_system_enabled = get_option('acb_support_system_enabled', false); // Fix: Ensure proper boolean conversion $support_system_enabled = ($support_system_enabled === '1' || $support_system_enabled === 1 || $support_system_enabled === true || $support_system_enabled === 'true'); wp_send_json_success([ 'support_system_enabled' => $support_system_enabled ]); } /** * Save support system settings - Only for administrators */ public function save_support_settings() { if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'acb_nonce' ) ) { wp_send_json_error( [ 'message' => __( 'Security check failed.','admin-chat-box' ) ] ); wp_die(); } if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( [ 'message' => __( 'Insufficient permissions.','admin-chat-box' ) ] ); wp_die(); } $support_system_enabled = isset( $_POST['support_system_enabled'] ) && in_array( $_POST['support_system_enabled'], [ 'true', true, '1', 1 ], true ); $result = update_option( 'acb_support_system_enabled', $support_system_enabled ); if ( $result || get_option( 'acb_support_system_enabled' ) == $support_system_enabled ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison wp_send_json_success( [ 'message' => __( 'Support system settings saved successfully.','admin-chat-box' ), 'support_system_enabled' => $support_system_enabled, ] ); } else { wp_send_json_error( [ 'message' => __( 'Failed to save support system settings.','admin-chat-box' ) ] ); } wp_die(); } /** * Get users with admin status - Available to all authenticated users (for React components) */ public function get_users_with_admin_status() { if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'acb_nonce' ) ) { wp_send_json_error( [ 'message' => __( 'Security check failed.','admin-chat-box' ) ] ); wp_die(); } if ( ! is_user_logged_in() ) { wp_send_json_error( [ 'message' => __( 'Authentication required.','admin-chat-box' ) ] ); wp_die(); } global $wpdb; $table_users = $wpdb->prefix . 'acb_users'; if ( $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table_users ) ) !== $table_users ) { wp_send_json_error( [ 'message' => __( 'Users table does not exist.','admin-chat-box' ) ] ); wp_die(); } $current_user_uid = isset( $_POST['current_user_uid'] ) ? sanitize_text_field( wp_unslash( $_POST['current_user_uid'] ) ) : ''; if ( ! empty( $current_user_uid ) ) { $users = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}acb_users WHERE firebase_uid != %s ORDER BY last_seen DESC", $current_user_uid ) ); } else { $users = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}acb_users ORDER BY last_seen DESC" ); } if ( false === $users ) { wp_send_json_error( [ 'message' => __( 'Failed to retrieve users.','admin-chat-box' ) ] ); wp_die(); } $formatted_users = []; foreach ($users as $user) { // Check if user is online (last seen within 2 minutes) $last_seen_time = strtotime($user->last_seen); $is_online = (time() - $last_seen_time) < 120; // 2 minutes $formatted_users[] = [ 'id' => absint($user->id), 'firebase_uid' => esc_html($user->firebase_uid), 'user_name' => esc_html($user->user_name), 'user_email' => esc_html($user->user_email), 'user_avatar' => esc_url($user->user_avatar), 'auth_provider' => esc_html($user->auth_provider), 'is_admin' => (bool) $user->is_admin, 'is_online' => $is_online, 'last_seen' => esc_html($user->last_seen), 'created_at' => esc_html($user->created_at), 'formatted_last_seen' => esc_html( wp_date( 'M d, Y > h:i A', strtotime( $user->last_seen ) ) ) ]; } wp_send_json_success([ 'users' => $formatted_users, 'total' => count($formatted_users), 'timestamp' => time() ]); } /** * Sync Firebase users to WordPress database - Only for administrators */ public function sync_firebase_users() { if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'acb_nonce' ) ) { wp_send_json_error( [ 'message' => __( 'Security check failed.','admin-chat-box' ) ] ); wp_die(); } if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( [ 'message' => __( 'Insufficient permissions.','admin-chat-box' ) ] ); wp_die(); } if ( ! isset( $_POST['firebase_users'] ) || empty( $_POST['firebase_users'] ) ) { wp_send_json_error( [ 'message' => __( 'No Firebase users data provided.','admin-chat-box' ) ] ); wp_die(); } $firebase_users_json = wp_unslash( $_POST['firebase_users'] ); $firebase_users = json_decode( $firebase_users_json, true ); if ( ! is_array( $firebase_users ) ) { wp_send_json_error( [ 'message' => __( 'Invalid Firebase users data format.','admin-chat-box' ) ] ); wp_die(); } $synced_count = 0; $errors = []; foreach ( $firebase_users as $fb_user ) { if ( ! isset( $fb_user['uid'] ) || ! isset( $fb_user['email'] ) ) { $errors[] = 'Missing required fields for user: ' . ( isset( $fb_user['email'] ) ? sanitize_email( $fb_user['email'] ) : 'unknown' ); continue; } $firebase_uid = sanitize_text_field( $fb_user['uid'] ); $user_name = sanitize_text_field( $fb_user['displayName'] ?? $fb_user['email'] ); $user_email = sanitize_email( $fb_user['email'] ); $user_avatar = isset( $fb_user['photoURL'] ) ? esc_url_raw( $fb_user['photoURL'] ) : ''; $auth_provider = sanitize_text_field( $fb_user['auth_provider'] ?? 'firebase' ); $result = $this->add_user_to_chat_table( $firebase_uid, $user_name, $user_email, $user_avatar, $auth_provider ); if ( false !== $result ) { $synced_count++; } else { $errors[] = 'Failed to sync user: ' . $user_email; } } if ( $synced_count > 0 ) { wp_send_json_success( [ 'message' => sprintf( __( 'Successfully synced %d users.','admin-chat-box' ), $synced_count ), 'synced_count' => $synced_count, 'errors' => $errors, ] ); } else { wp_send_json_error( [ 'message' => __( 'No users were synced.','admin-chat-box' ), 'errors' => $errors ] ); } wp_die(); } /** * Add user to chat users table */ private function add_user_to_chat_table($firebase_uid, $user_name, $user_email, $user_avatar, $auth_provider) { global $wpdb; $table_users = $wpdb->prefix . 'acb_users'; // Validate table exists if ($wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $table_users)) !== $table_users) { if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log error_log( 'ACB: Chat users table does not exist: ' . esc_attr( $table_users ) ); } return false; } // Check if user already exists in chat table $existing_user = $wpdb->get_row( $wpdb->prepare("SELECT * FROM {$wpdb->prefix}acb_users WHERE firebase_uid = %s", $firebase_uid) ); if ($existing_user) { // Update existing user $result = $wpdb->update( $table_users, [ 'user_name' => $user_name, 'user_email' => $user_email, 'user_avatar' => $user_avatar, 'auth_provider' => $auth_provider, 'last_seen' => current_time('mysql'), 'updated_at' => current_time('mysql') ], ['firebase_uid' => $firebase_uid], ['%s', '%s', '%s', '%s', '%s', '%s'], ['%s'] ); if ($result !== false) { if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log error_log( 'ACB: Updated existing chat user: ' . esc_attr( $user_email ) ); } return $existing_user->id; } } else { // Create new user in chat table $result = $wpdb->insert( $table_users, [ 'firebase_uid' => $firebase_uid, 'user_name' => $user_name, 'user_email' => $user_email, 'user_avatar' => $user_avatar, 'auth_provider' => $auth_provider, 'is_admin' => 0, // Default to regular user 'last_seen' => current_time('mysql'), 'created_at' => current_time('mysql'), 'updated_at' => current_time('mysql') ], ['%s', '%s', '%s', '%s', '%s', '%d', '%s', '%s', '%s'] ); if ($result !== false) { $new_user_id = $wpdb->insert_id; if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log error_log( 'ACB: Created new chat user: ' . esc_attr( $user_email ) . ' (ID: ' . absint( $new_user_id ) . ')' ); } return $new_user_id; } } if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log error_log( 'ACB: Failed to add/update user in chat table: ' . esc_attr( $user_email ) ); } return false; } /** * Check if user is admin in chat system - Available to all users */ public function check_user_admin_status() { // Verify nonce if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'acb_nonce' ) ) { wp_send_json_error([ 'message' => __( 'Security check failed.','admin-chat-box' ), ]); wp_die(); } // Issue 2.3: Only logged-in users should query admin status. if ( ! is_user_logged_in() ) { wp_send_json_error( [ 'message' => __( 'Authentication required.','admin-chat-box' ) ] ); wp_die(); } if (!isset($_POST['firebase_uid']) || empty(trim($_POST['firebase_uid']))) { wp_send_json_error('Firebase UID is required'); wp_die(); } $firebase_uid = sanitize_text_field(wp_unslash($_POST['firebase_uid'])); global $wpdb; $table_users = $wpdb->prefix . 'acb_users'; // Validate table exists if ($wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $table_users)) !== $table_users) { wp_send_json_error('Users table does not exist'); wp_die(); } // Get user from database $user = $wpdb->get_row( $wpdb->prepare("SELECT * FROM {$wpdb->prefix}acb_users WHERE firebase_uid = %s", $firebase_uid) ); if ( ! $user ) { // User not found in database, they are regular by default wp_send_json_success( [ 'is_admin' => false, 'message' => __( 'User not found in database, defaulting to regular user.','admin-chat-box' ), ] ); } else { wp_send_json_success( [ 'is_admin' => (bool) $user->is_admin, 'user_id' => absint( $user->id ), 'user_name' => esc_html( $user->user_name ), ] ); } wp_die(); } /** * Get frontend widget settings - Available to all users */ public function get_widget_settings() { if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'acb_nonce' ) ) { wp_send_json_error( [ 'message' => __( 'Security check failed.','admin-chat-box' ) ] ); wp_die(); } global $wpdb; $table_settings = $wpdb->prefix . 'acb_settings'; // Get widget settings from database $widget_settings = []; $settings_keys = [ 'frontend_widget_enabled', 'widget_position', 'widget_title', 'widget_description', 'widget_primary_color', 'widget_show_on_pages', 'widget_exclude_pages' ]; // Default values $defaults = [ 'frontend_widget_enabled' => true, 'widget_position' => 'bottom-right', 'widget_title' => 'Chat Support', 'widget_description' => 'Need help? Chat with our team!', 'widget_primary_color' => '#5A5EB9', 'widget_show_on_pages' => 'all', 'widget_exclude_pages' => '' ]; foreach ($settings_keys as $key) { $value = $wpdb->get_var( $wpdb->prepare("SELECT setting_value FROM {$wpdb->prefix}acb_settings WHERE setting_key = %s", $key) ); // Handle boolean conversion for frontend_widget_enabled if ($key === 'frontend_widget_enabled') { if ($value !== null) { $widget_settings[$key] = ($value === '1' || $value === 'true' || $value === true || $value === 1); } else { $widget_settings[$key] = $defaults[$key]; } } else { // Use database value if exists, otherwise use default $widget_settings[$key] = $value !== null ? $value : $defaults[$key]; } } wp_send_json_success( [ 'widget_settings' => $widget_settings ] ); wp_die(); } /** * Save frontend widget settings - Only for administrators */ public function save_widget_settings() { if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'acb_nonce' ) ) { wp_send_json_error( [ 'message' => __( 'Security check failed.','admin-chat-box' ) ] ); wp_die(); } if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( [ 'message' => __( 'Insufficient permissions.','admin-chat-box' ) ] ); wp_die(); } $settings = []; $allowed_settings = [ 'frontend_widget_enabled', 'widget_position', 'widget_title', 'widget_description', 'widget_primary_color', 'widget_show_on_pages', 'widget_exclude_pages', ]; foreach ( $allowed_settings as $key ) { if ( isset( $_POST[ $key ] ) ) { $settings[ $key ] = sanitize_text_field( wp_unslash( $_POST[ $key ] ) ); } } if ( isset( $settings['widget_position'] ) ) { $allowed_positions = [ 'bottom-right', 'bottom-left', 'top-right', 'top-left' ]; if ( ! in_array( $settings['widget_position'], $allowed_positions, true ) ) { wp_send_json_error( [ 'message' => __( 'Invalid widget position.','admin-chat-box' ) ] ); wp_die(); } } if ( isset( $settings['widget_show_on_pages'] ) ) { $allowed_show_options = [ 'all', 'specific', 'exclude' ]; if ( ! in_array( $settings['widget_show_on_pages'], $allowed_show_options, true ) ) { wp_send_json_error( [ 'message' => __( 'Invalid show on pages option.','admin-chat-box' ) ] ); wp_die(); } } global $wpdb; $table_settings = $wpdb->prefix . 'acb_settings'; $saved_count = 0; foreach ($settings as $key => $value) { $result = $wpdb->replace( $table_settings, [ 'setting_key' => $key, 'setting_value' => $value, 'updated_at' => current_time('mysql') ], ['%s', '%s', '%s'] ); if ($result !== false) { $saved_count++; } } if ( $saved_count > 0 ) { wp_send_json_success( [ 'message' => __( 'Widget settings saved successfully.','admin-chat-box' ), 'saved_count' => $saved_count, ] ); } else { wp_send_json_error( [ 'message' => __( 'Failed to save widget settings.','admin-chat-box' ) ] ); } wp_die(); } /** * Refresh nonce — no nonce verification needed since this endpoint issues a new one. */ public function refresh_nonce() { wp_send_json_success( [ 'nonce' => wp_create_nonce( 'acb_nonce' ) ] ); wp_die(); } }