From 999c2cc8662da1c76be86bb15c983ed163e33528 Mon Sep 17 00:00:00 2001 From: Desmond Date: Mon, 9 Feb 2026 21:30:13 -0800 Subject: [PATCH] Add nonces for security dry up redundencies --- assets/js/dashboard.js | 1 + hi-school-slide-manager.php | 44 ------------------------------ includes/class-hssm-frontend.php | 28 +++++++++++++++---- includes/class-hssm-main.php | 20 ++++++++++++-- includes/class-hssm-slides-cpt.php | 2 +- 5 files changed, 43 insertions(+), 52 deletions(-) diff --git a/assets/js/dashboard.js b/assets/js/dashboard.js index bb30064..7fce117 100644 --- a/assets/js/dashboard.js +++ b/assets/js/dashboard.js @@ -474,6 +474,7 @@ $form.addClass('hssm-loading'); + formData.append('nonce', hssmDashboard.nonce); $.ajax({ url: hssmDashboard.ajaxurl, type: 'POST', diff --git a/hi-school-slide-manager.php b/hi-school-slide-manager.php index 9dcb5ff..12c45b5 100644 --- a/hi-school-slide-manager.php +++ b/hi-school-slide-manager.php @@ -36,50 +36,6 @@ define( 'HSSM_PLUGIN_BASENAME', plugin_basename( __FILE__ ) ); require_once HSSM_PLUGIN_DIR . 'includes/class-hssm-autoloader.php'; require_once HSSM_PLUGIN_DIR . 'includes/class-hssm-main.php'; -/** - * Plugin activation hook - * - * @since 1.0.0 - */ -function hssm_activate() { - // Create custom capability - $admin_role = get_role( 'administrator' ); - if ( $admin_role ) { - $admin_role->add_cap( 'hssm_manage_slides' ); - } - - // Also add to editor role - $editor_role = get_role( 'editor' ); - if ( $editor_role ) { - $editor_role->add_cap( 'hssm_manage_slides' ); - } - - // Flush rewrite rules to ensure our CPT permalinks work - flush_rewrite_rules(); -} -register_activation_hook( __FILE__, 'hssm_activate' ); - -/** - * Plugin deactivation hook - * - * @since 1.0.0 - */ -function hssm_deactivate() { - // Remove custom capability - $admin_role = get_role( 'administrator' ); - if ( $admin_role ) { - $admin_role->remove_cap( 'hssm_manage_slides' ); - } - - $editor_role = get_role( 'editor' ); - if ( $editor_role ) { - $editor_role->remove_cap( 'hssm_manage_slides' ); - } - - // Flush rewrite rules - flush_rewrite_rules(); -} -register_deactivation_hook( __FILE__, 'hssm_deactivate' ); /** * Initialize the Hi-School Slide Manager plugin diff --git a/includes/class-hssm-frontend.php b/includes/class-hssm-frontend.php index e439f27..9a7a406 100644 --- a/includes/class-hssm-frontend.php +++ b/includes/class-hssm-frontend.php @@ -44,7 +44,7 @@ class HSSM_Frontend { // AJAX handlers add_action( 'wp_ajax_hssm_save_slide', array( $this, 'ajax_save_slide' ) ); - add_action( 'wp_ajax_hssm_upload_image', array( $this, 'ajax_upload_image' ) ); // Added missing upload handler + add_action( 'wp_ajax_hssm_upload_image', array( $this, 'ajax_upload_image' ) ); add_action( 'wp_ajax_hssm_get_slides', array( $this, 'ajax_get_slides' ) ); add_action( 'wp_ajax_hssm_delete_slide', array( $this, 'ajax_delete_slide' ) ); add_action( 'wp_ajax_hssm_update_slide', array( $this, 'ajax_update_slide' ) ); @@ -53,15 +53,12 @@ class HSSM_Frontend { add_action( 'wp_ajax_hssm_duplicate_slide', array( $this, 'ajax_duplicate_slide' ) ); add_action( 'wp_ajax_hssm_toggle_slide_status', array( $this, 'ajax_toggle_slide_status' ) ); add_action( 'wp_ajax_hssm_approve_slide', array( $this, 'ajax_approve_slide' ) ); - add_action( 'wp_ajax_hssm_preview_slides', array( $this, 'ajax_preview_slides' ) ); // Added missing preview handler + add_action( 'wp_ajax_hssm_preview_slides', array( $this, 'ajax_preview_slides' ) ); // Notification Settings AJAX add_action( 'wp_ajax_hssm_get_notification_settings', array( $this, 'ajax_get_notification_settings' ) ); add_action( 'wp_ajax_hssm_save_notification_settings', array( $this, 'ajax_save_notification_settings' ) ); - // Add nopriv versions (this shouldn't be needed but let's test) - add_action( 'wp_ajax_nopriv_hssm_get_slides', array( $this, 'ajax_get_slides' ) ); - // Test handler to verify AJAX is working add_action( 'wp_ajax_hssm_test', array( $this, 'ajax_test' ) ); add_action( 'wp_ajax_nopriv_hssm_test', array( $this, 'ajax_test' ) ); @@ -681,6 +678,15 @@ class HSSM_Frontend { * @since 1.0.0 */ public function ajax_get_slides() { + if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( $_POST['nonce'], 'hssm_dashboard_nonce' ) ) { + wp_send_json_error( array( 'message' => 'Nonce verification failed' ) ); + return; + } + + if ( ! current_user_can( 'edit_posts' ) ) { + wp_send_json_error( array( 'message' => 'You do not have permission to view slides.' ) ); + return; + } // Get pagination parameters $page = isset( $_POST['page'] ) ? intval( $_POST['page'] ) : 1; $per_page = isset( $_POST['per_page'] ) ? intval( $_POST['per_page'] ) : 25; @@ -849,6 +855,10 @@ class HSSM_Frontend { * @since 1.0.0 */ public function ajax_approve_slide() { + if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( $_POST['nonce'], 'hssm_dashboard_nonce' ) ) { + wp_send_json_error( array( 'message' => 'Nonce verification failed' ) ); + return; + } error_log( 'Approve slide AJAX called' ); if ( empty( $_POST['slide_id'] ) ) { @@ -924,6 +934,10 @@ class HSSM_Frontend { * @since 1.0.0 */ public function ajax_delete_slide() { + if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( $_POST['nonce'], 'hssm_dashboard_nonce' ) ) { + wp_send_json_error( array( 'message' => 'Nonce verification failed' ) ); + return; + } if ( empty( $_POST['slide_id'] ) ) { wp_send_json_error( array( 'message' => 'Slide ID is required' ) ); } @@ -956,6 +970,10 @@ class HSSM_Frontend { * @since 1.0.0 */ public function ajax_update_slide() { + if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( $_POST['nonce'], 'hssm_dashboard_nonce' ) ) { + wp_send_json_error( array( 'message' => 'Nonce verification failed' ) ); + return; + } if ( empty( $_POST['slide_id'] ) ) { wp_send_json_error( array( 'message' => 'Slide ID is required' ) ); } diff --git a/includes/class-hssm-main.php b/includes/class-hssm-main.php index e08c2a1..f350f07 100644 --- a/includes/class-hssm-main.php +++ b/includes/class-hssm-main.php @@ -175,8 +175,6 @@ class HSSM_Main { // AJAX hooks for authenticated users // Note: Main AJAX handlers are in HSSM_Frontend class - add_action( 'wp_ajax_hssm_upload_image', array( $this, 'ajax_upload_image' ) ); - add_action( 'wp_ajax_hssm_preview_slides', array( $this, 'ajax_preview_slides' ) ); add_action( 'wp_ajax_hssm_send_preview_email', array( $this, 'ajax_send_preview_email' ) ); // Cron hooks for scheduled slides @@ -352,6 +350,15 @@ class HSSM_Main { * @since 1.0.0 */ public static function activate() { + // Create custom capability + $roles = [ 'administrator', 'editor' ]; + foreach ( $roles as $role_name ) { + $role = get_role( $role_name ); + if ( $role ) { + $role->add_cap( 'hssm_manage_slides' ); + } + } + // Set up cron jobs self::setup_cron_jobs(); @@ -371,6 +378,15 @@ class HSSM_Main { * @since 1.0.0 */ public static function deactivate() { + // Remove custom capability + $roles = [ 'administrator', 'editor' ]; + foreach ( $roles as $role_name ) { + $role = get_role( $role_name ); + if ( $role ) { + $role->remove_cap( 'hssm_manage_slides' ); + } + } + // Clear cron jobs wp_clear_scheduled_hook( 'hssm_check_scheduled_slides' ); diff --git a/includes/class-hssm-slides-cpt.php b/includes/class-hssm-slides-cpt.php index 745a366..347a0cf 100644 --- a/includes/class-hssm-slides-cpt.php +++ b/includes/class-hssm-slides-cpt.php @@ -928,7 +928,7 @@ class HSSM_Slides_CPT { public function ajax_update_slide_order() { // Verify nonce and permissions if ( ! wp_verify_nonce( $_POST['nonce'], 'hssm_update_slide_order' ) || ! current_user_can( 'edit_posts' ) ) { - wp_die( 'Unauthorized' ); + wp_send_json_error( 'Unauthorized' ); } if ( isset( $_POST['slide_ids'] ) && is_array( $_POST['slide_ids'] ) ) {