Changes in wicked-folders/trunk [2805161:2860994]
- Location:
- wicked-folders/trunk
- Files:
-
- 7 edited
-
admin-templates/object-folder-pane.php (modified) (1 diff)
-
js/admin.js (modified) (2 diffs)
-
js/app.js (modified) (11 diffs)
-
lib/class-wicked-folders-admin.php (modified) (2 diffs)
-
lib/class-wicked-folders-ajax.php (modified) (14 diffs)
-
readme.txt (modified) (2 diffs)
-
wicked-folders.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
wicked-folders/trunk/admin-templates/object-folder-pane.php
r2805161 r2860994 223 223 folders: folders, 224 224 screen: '<?php echo esc_attr( $screen->id ); ?>', 225 nonce: '<?php echo wp_create_nonce( 'wicked_folders_ save_state' ); ?>',225 nonce: '<?php echo wp_create_nonce( 'wicked_folders_ajax_action' ); ?>', 226 226 treePaneWidth: <?php echo ( int ) $state->tree_pane_width; ?>, 227 227 //hideAssignedItems: <?php echo ( int ) $state->hide_assigned_items; ?>, -
wicked-folders/trunk/js/admin.js
r2805161 r2860994 4 4 $( this ).parents( '.notice' ).slideUp(); 5 5 var key = $( this ).attr( 'data-key' ); 6 var nonce = $( this ).attr( 'data-nonce' ); 6 7 $.ajax( 7 8 ajaxurl, … … 9 10 data: { 10 11 'action': 'wicked_folders_dismiss_message', 12 'nonce': nonce, 11 13 'key': key 12 14 }, -
wicked-folders/trunk/js/app.js
r2805161 r2860994 53 53 assignable: true, 54 54 ownerId: 0, 55 ownerName: '' 55 ownerName: '', 56 nonce: false 56 57 }, 57 58 … … 62 63 } 63 64 65 this.set( 'nonce', wickedFoldersSettings.saveFolderNonce ); 64 66 }, 65 67 … … 76 78 taxonomy = this.get( 'taxonomy' ), 77 79 action = this.get( '_actionOverride' ) || 'wicked_folders_save_folder', 78 methodOverride = this.get( '_methodOverride' ) || false; 80 methodOverride = this.get( '_methodOverride' ) || false, 81 nonce = this.get( 'nonce' ); 79 82 80 83 // We need the ID and taxonomy attributes when deleting 81 var url = wickedFoldersSettings.ajaxURL + '?action=' + action + '&id=' + id + '&taxonomy=' + taxonomy ;84 var url = wickedFoldersSettings.ajaxURL + '?action=' + action + '&id=' + id + '&taxonomy=' + taxonomy + '&nonce=' + nonce; 82 85 83 86 // Assume we're updating if we have an ID … … 102 105 data: { 103 106 'action': 'wicked_folders_clone_folder', 107 'nonce': this.get( 'nonce' ), 104 108 'id': this.id, 105 109 'post_type': this.get( 'postType' ), … … 355 359 data: { 356 360 'action': 'wicked_folders_save_folder_order', 361 'nonce': wickedFoldersSettings.saveFolderNonce, 357 362 'folders': folders 358 363 }, … … 892 897 hideAssignedItems: true, 893 898 orderby: 'title', 894 order: 'asc' 899 order: 'asc', 900 nonce: false 895 901 }, 896 902 … … 926 932 data: { 927 933 'action': 'wicked_folders_move_object', 928 //'nonce': WickedFolderSettings.moveObjectNonce,934 'nonce': model.get( 'nonce' ), 929 935 'object_type': objectType, 930 936 'object_id': objectId, … … 953 959 data: { 954 960 'action': 'wicked_folders_unassign_folders', 961 'nonce': model.get( 'nonce' ), 955 962 'object_id': objectId, 956 963 'taxonomy': model.get( 'taxonomy' ) … … 1002 1009 showItemCount: true, 1003 1010 enableCreate: true, 1004 enableAssign: true 1011 enableAssign: true, 1012 nonce: false 1005 1013 }, 1006 1014 … … 2994 3002 var posts = view.model.get( 'postsToMove' ), 2995 3003 objectIds = posts.pluck( 'id' ), 2996 controller = new wickedfolders.models.FolderBrowserController( ),3004 controller = new wickedfolders.models.FolderBrowserController( { nonce: view.model.get( 'nonce' ) } ), 2997 3005 taxonomy = view.folder().get('taxonomy' ), 2998 3006 folder = view.folder(), … … 3074 3082 changedFolders = new wickedfolders.collections.Folders(); 3075 3083 3076 var controller = new wickedfolders.models.FolderBrowserController( );3084 var controller = new wickedfolders.models.FolderBrowserController( { nonce: view.model.get( 'nonce' ) } ); 3077 3085 3078 3086 items.each( function( index, item ){ -
wicked-folders/trunk/lib/class-wicked-folders-admin.php
r2805161 r2860994 81 81 public function admin_notices() { 82 82 $dismissed_messages = ( array ) get_user_option( 'wicked_folders_dismissed_messages' ); 83 $nonce = wp_create_nonce( 'wicked_folders_dismiss_message_ajax_action' ); 83 84 if ( $this->is_folder_pane_enabled_page() && ! in_array( 'toggle_folder_pane_hint', $dismissed_messages ) ) { 84 $this->add_admin_notice( __( "Hint: The folders pane can be toggled on or off. To hide the folder pane, click the 'Toggle folders' link in the admin menu on the side of the screen.", 'wicked-folders' ) . '<a class="wicked-dismiss" href="#" data-key="toggle_folder_pane_hint" >' . __( 'Dismiss', 'wicked-folders' ) . '</a>', 'notice notice-success wicked-dismissable' );85 $this->add_admin_notice( __( "Hint: The folders pane can be toggled on or off. To hide the folder pane, click the 'Toggle folders' link in the admin menu on the side of the screen.", 'wicked-folders' ) . '<a class="wicked-dismiss" href="#" data-key="toggle_folder_pane_hint" data-nonce="' . $nonce . '">' . __( 'Dismiss', 'wicked-folders' ) . '</a>', 'notice notice-success wicked-dismissable' ); 85 86 } 86 87 foreach ( Wicked_Folders_Admin::$admin_notices as $notice ) { … … 205 206 'afterAjaxScripts' => apply_filters( 'wicked_folders_after_ajax_scripts', $after_ajax_scripts ), 206 207 'isElementorActive' => isset( $_GET['action'] ) && 'elementor' == $_GET['action'] ? true : false, 208 'saveFolderNonce' => wp_create_nonce( 'wicked_folders_save_folder_ajax_action' ), 207 209 ) ); 208 210 -
wicked-folders/trunk/lib/class-wicked-folders-ajax.php
r2805161 r2860994 14 14 add_action( 'wp_ajax_wicked_folders_save_state', array( $this, 'ajax_save_state' ) ); 15 15 add_action( 'wp_ajax_wicked_folders_move_object', array( $this, 'ajax_move_object' ) ); 16 add_action( 'wp_ajax_wicked_folders_add_folder', array( $this, 'ajax_add_folder' ) );17 16 add_action( 'wp_ajax_wicked_folders_clone_folder', array( $this, 'ajax_clone_folder' ) ); 18 add_action( 'wp_ajax_wicked_folders_edit_folder', array( $this, 'ajax_edit_folder' ) );19 add_action( 'wp_ajax_wicked_folders_delete_folder', array( $this, 'ajax_delete_folder' ) );20 17 add_action( 'wp_ajax_wicked_folders_save_folder', array( $this, 'ajax_save_folder' ) ); 21 add_action( 'wp_ajax_wicked_folders_save_sort_order', array( $this, 'ajax_save_sort_order' ) );22 18 add_action( 'wp_ajax_wicked_folders_dismiss_message', array( $this, 'ajax_dismiss_message' ) ); 23 19 add_action( 'wp_ajax_wicked_folders_get_child_folders', array( $this, 'ajax_get_child_folders' ) ); … … 42 38 */ 43 39 public function ajax_move_object() { 44 45 40 $result = array( 'error' => false, 'items' => array(), 'folders' => array() ); 46 41 $nonce = isset( $_REQUEST['nonce'] ) ? sanitize_text_field( $_REQUEST['nonce'] ) : false; … … 51 46 $post_type = isset( $_REQUEST['post_type'] ) ? sanitize_text_field( $_REQUEST['post_type'] ) : false; 52 47 53 /* 54 if ( ! wp_verify_nonce( $nonce, 'wicked_folders_move_object' ) ) { 55 $result['error'] = true; 56 } 57 */ 48 if ( ! wp_verify_nonce( $nonce, 'wicked_folders_ajax_action' ) ) { 49 wp_send_json_error( null, 403 ); 50 } 51 52 if ( ! current_user_can( 'edit_posts' ) ) { 53 wp_send_json_error( null, 403 ); 54 } 58 55 59 56 if ( ! $object_type || ! false === $object_id || ! false === $destination_object_id ) { … … 81 78 */ 82 79 public function ajax_unassign_folders() { 83 84 80 $result = array( 'error' => false, 'items' => array(), 'folders' => array() ); 85 81 $nonce = isset( $_REQUEST['nonce'] ) ? sanitize_text_field( $_REQUEST['nonce'] ) : false; … … 90 86 $user_id = get_current_user_id(); 91 87 88 if ( ! wp_verify_nonce( $nonce, 'wicked_folders_ajax_action' ) ) { 89 wp_send_json_error( null, 403 ); 90 } 91 92 if ( ! current_user_can( 'edit_posts' ) ) { 93 wp_send_json_error( null, 403 ); 94 } 95 92 96 if ( class_exists( 'Wicked_Folders_Folder_Collection_Policy' ) ) { 93 97 $policy = Wicked_Folders_Folder_Collection_Policy::get_taxonomy_policy( $taxonomy ); 94 98 } 95 96 /*97 if ( ! wp_verify_nonce( $nonce, 'wicked_folders_move_object' ) ) {98 $result['error'] = true;99 }100 */101 99 102 100 if ( ! $taxonomy ) { … … 142 140 $result = array( 'error' => false ); 143 141 $data = json_decode( file_get_contents( 'php://input' ) ); 144 //$nonce = $data->nonce;142 $nonce = $data->nonce; 145 143 $screen = $data->screen; 146 144 $state = new Wicked_Folders_Screen_State( $screen, get_current_user_id(), $data->lang ); 145 146 if ( ! wp_verify_nonce( $nonce, 'wicked_folders_ajax_action' ) ) { 147 wp_send_json_error( null, 403 ); 148 } 149 150 if ( ! current_user_can( 'edit_posts' ) ) { 151 wp_send_json_error( null, 403 ); 152 } 147 153 148 154 $state->folder = isset( $data->folder->id ) ? $data->folder->id : '0'; … … 167 173 } 168 174 169 public function ajax_add_folder() {170 171 $this->ajax_edit_folder();172 173 }174 175 public function ajax_edit_folder() {176 177 $result = array( 'error' => false, 'message' => __( 'An error occurred. Please try again.', 'wicked-folders' ) );178 $nonce = isset( $_REQUEST['nounce'] ) ? sanitize_text_field( $_REQUEST['nounce'] ) : false;179 $id = isset( $_REQUEST['id'] ) ? ( int ) $_REQUEST['id'] : false;180 $name = isset( $_REQUEST['name'] ) ? sanitize_text_field( $_REQUEST['name'] ) : false;181 $parent = isset( $_REQUEST['parent'] ) ? ( int ) $_REQUEST['parent'] : false;182 $post_type = isset( $_REQUEST['post_type'] ) ? sanitize_key( $_REQUEST['post_type'] ) : false;183 $tax_name = Wicked_Folders::get_tax_name( $post_type );184 $url = admin_url( 'edit.php?post_type=' . $post_type . '&page=' . $tax_name );185 186 //if ( ! wp_verify_nonce( $nonce, 'wicked_folders_add_folder' ) ) {187 // $result['error'] = true;188 //}189 190 if ( ! $name || ! $post_type ) {191 $result['message'] = __( 'Invalid name or post type.', 'wicked-folders' );192 $result['error'] = true;193 }194 195 if ( -1 == $parent || false === $parent ) {196 $parent = 0;197 }198 199 if ( ! $result['error'] ) {200 if ( $id ) {201 $existing_term = get_term_by( 'name', $name, $tax_name );202 // Don't allow terms with the same name at the same level203 if ( $existing_term && $existing_term->parent == $parent ) {204 $term = new WP_Error( 'term_exists' );205 } else {206 $term = wp_update_term( $id, $tax_name, array(207 'name' => $name,208 'parent' => $parent,209 ) );210 }211 } else {212 $term = wp_insert_term( $name, $tax_name, array(213 'parent' => $parent,214 ) );215 }216 if ( is_wp_error( $term ) ) {217 if ( isset( $term->errors['term_exists'] ) ) {218 $result['message'] = __( 'A folder with that name already exists in the selected parent folder. Please enter a different name or select a different parent folder.', 'wicked-folders' );219 } else {220 $result['message'] = $term->get_error_message();221 }222 $result['error'] = true;223 } else {224 $select = wp_dropdown_categories( array(225 'orderby' => 'name',226 'order' => 'ASC',227 'show_option_none' => '— ' . __( 'Parent Folder', 'wicked-folders' ) . ' —',228 'taxonomy' => $tax_name,229 'depth' => 0,230 'hierarchical' => true,231 'hide_empty' => false,232 'selected' => $parent,233 'echo' => false,234 'option_none_value' => 0,235 ) );236 $result = array(237 'error' => false,238 'folderId' => $term['term_id'],239 'folderUrl' => add_query_arg( 'folder', $term['term_id'], $url ),240 'select' => $select,241 );242 }243 }244 245 echo json_encode( $result );246 247 wp_die();248 249 }250 251 public function ajax_delete_folder() {252 253 // TODO: check nonce254 $result = array( 'error' => false );255 $nonce = isset( $_REQUEST['nounce'] ) ? sanitize_text_field( $_REQUEST['nounce'] ) : false;256 $id = isset( $_REQUEST['id'] ) ? ( int ) $_REQUEST['id'] : false;257 $post_type = isset( $_REQUEST['post_type'] ) ? sanitize_key( $_REQUEST['post_type'] ) : false;258 $taxonomy = isset( $_REQUEST['taxonomy'] ) ? sanitize_key( $_REQUEST['taxonomy'] ) : Wicked_Folders::get_tax_name( $post_type );259 260 $delete_result = wp_delete_term( $id, $taxonomy );261 262 if ( is_wp_error( $delete_result ) ) {263 $result['error'] = true;264 $result['message'] = $delete_result->get_error_message();265 }266 267 echo json_encode( $result );268 269 wp_die();270 271 }272 273 175 public function ajax_save_folder() { 274 275 176 $response = array( 'error' => false ); 276 //$method = $_SERVER['REQUEST_METHOD'];177 $nonce = isset( $_REQUEST['nonce'] ) ? sanitize_text_field( $_REQUEST['nonce'] ) : false; 277 178 $method = isset( $_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'] ) ? $_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'] : 'POST'; 278 179 $method = isset( $_REQUEST['_method_override'] ) ? sanitize_text_field( $_REQUEST['_method_override'] ) : $method; … … 280 181 $policy = false; 281 182 $user_id = get_current_user_id(); 183 184 if ( ! wp_verify_nonce( $nonce, 'wicked_folders_save_folder_ajax_action' ) ) { 185 wp_send_json_error( null, 403 ); 186 } 187 188 if ( ! current_user_can( 'edit_posts' ) ) { 189 wp_send_json_error( null, 403 ); 190 } 282 191 283 192 if ( 'DELETE' == $method ) { … … 389 298 public function ajax_clone_folder() { 390 299 $folders = array(); 300 $nonce = isset( $_REQUEST['nonce'] ) ? sanitize_text_field( $_REQUEST['nonce'] ) : false; 391 301 $id = isset( $_REQUEST['id'] ) ? ( int ) $_REQUEST['id'] : false; 392 302 $post_type = isset( $_REQUEST['post_type'] ) ? sanitize_key( $_REQUEST['post_type'] ) : false; … … 395 305 $taxonomy = Wicked_Folders::get_tax_name( $post_type ); 396 306 $user_id = get_current_user_id(); 307 308 if ( ! wp_verify_nonce( $nonce, 'wicked_folders_save_folder_ajax_action' ) ) { 309 wp_send_json_error( null, 403 ); 310 } 311 312 if ( ! current_user_can( 'edit_posts' ) ) { 313 wp_send_json_error( null, 403 ); 314 } 397 315 398 316 try { … … 424 342 } 425 343 426 public function ajax_save_sort_order() {427 428 global $wpdb;429 430 $new_order = array();431 $screen = sanitize_text_field( $_REQUEST['screen'] );432 $folder_id = sanitize_text_field( $_REQUEST['folder_id'] );433 $post_type = sanitize_text_field( $_REQUEST['post_type'] );434 $taxonomy = sanitize_text_field( $_REQUEST['taxonomy'] );435 $object_ids = array_map( 'absint', $_REQUEST['object_ids'] );436 $order = sanitize_text_field( $_REQUEST['order'] );437 $orderby = sanitize_text_field( $_REQUEST['orderby'] );438 $page_number = ( int ) $_REQUEST['page_number'];439 $items_per_page = ( int ) $_REQUEST['items_per_page'];440 $sort_key = '_wicked_folder_order__' . $taxonomy . '__' . $folder_id;441 $before = $items_per_page * ( $page_number - 1 );442 $after = $before + $items_per_page;443 444 // Initialize folder order. This will ensure that every post in the folder445 // has an order meta key so that we can update later446 Wicked_Folders::initalize_folder_order( $folder_id, $taxonomy );447 448 // Get IDs of posts assigned to the folder ordered the same way as they449 // were prior to changing the sort order450 $q = array(451 'post_type' => $post_type,452 'posts_per_page' => -1,453 'fields' => 'ids',454 'order' => $order,455 'orderby' => $orderby,456 'tax_query' => array(457 array(458 'taxonomy' => $taxonomy,459 'field' => 'term_id',460 'terms' => ( int ) $folder_id,461 )462 )463 );464 465 if ( 'wicked_folder_order' == $orderby ) {466 $q['orderby'] = array(467 'meta_value_num' => $order,468 'title' => 'ASC',469 );470 $q['meta_key'] = $sort_key;471 }472 473 $post_ids = get_posts( $q );474 475 $n = count( $post_ids );476 477 // Get the order of posts on previous pages478 for ( $i = 0; $i < $before; $i++ ) {479 $new_order[] = $post_ids[ $i ];480 }481 482 // Append the new order of posts for the current page483 $new_order = array_merge( $new_order, $object_ids );484 485 // Add posts from subsequent pages486 for ( $i = $after; $i < $n; $i++ ) {487 $new_order[] = $post_ids[ $i ];488 }489 490 // Get the current sort orders491 $current_order = $wpdb->get_results( $wpdb->prepare( "SELECT post_id, meta_value FROM {$wpdb->prefix}postmeta WHERE meta_key = %s ORDER BY post_id", $sort_key ), OBJECT_K );492 493 foreach ( $new_order as $index => $post_id ) {494 $sort = ( $n - $index ) * -1;495 // Only update posts where the sort order has changed496 if ( $sort != $current_order[ $post_id ]->meta_value ) {497 $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->prefix}postmeta SET meta_value = %s WHERE post_id = %d AND meta_key = %s", $sort, $post_id, $sort_key ) );498 }499 }500 501 }502 503 344 public function ajax_dismiss_message() { 345 $nonce = isset( $_REQUEST['nonce'] ) ? sanitize_text_field( $_REQUEST['nonce'] ) : false; 504 346 $result = array( 'error' => false ); 505 347 $dismissed_messages = ( array ) get_user_option( 'wicked_folders_dismissed_messages' ); 506 348 $dismissed_messages[] = $_POST['key']; 349 350 if ( ! wp_verify_nonce( $nonce, 'wicked_folders_dismiss_message_ajax_action' ) ) { 351 wp_send_json_error( null, 403 ); 352 } 507 353 508 354 update_user_meta( get_current_user_id(), 'wicked_folders_dismissed_messages', $dismissed_messages ); … … 521 367 $post_type = sanitize_key( $_REQUEST['post_type'] ); 522 368 369 if ( ! current_user_can( 'edit_posts' ) ) { 370 wp_send_json_error( null, 403 ); 371 } 372 523 373 $folder = Wicked_Folders::get_dynamic_folder( $folder_type, $folder_id, $post_type ); 524 374 … … 536 386 global $wpdb; 537 387 388 $nonce = isset( $_REQUEST['nonce'] ) ? sanitize_text_field( $_REQUEST['nonce'] ) : false; 538 389 $result = array( 'error' => false ); 539 390 $folders = isset( $_REQUEST['folders'] ) && is_array( $_REQUEST['folders' ] ) ? array_map( array( $this, 'sanitize_folder_order_param' ), $_REQUEST['folders'] ) : array(); 540 391 $order_field_exists = Wicked_Folders::get_instance()->term_order_field_exists(); 392 393 if ( ! wp_verify_nonce( $nonce, 'wicked_folders_save_folder_ajax_action' ) ) { 394 wp_send_json_error( null, 403 ); 395 } 396 397 if ( ! current_user_can( 'edit_posts' ) ) { 398 wp_send_json_error( null, 403 ); 399 } 541 400 542 401 foreach ( $folders as $folder ) { … … 567 426 $taxonomy = isset( $_GET['taxonomy'] ) ? sanitize_text_field( $_GET['taxonomy'] ) : false; 568 427 428 if ( ! current_user_can( 'edit_posts' ) ) { 429 wp_send_json_error( null, 403 ); 430 } 431 569 432 if ( $taxonomy ) { 570 433 $post_type = Wicked_Folders::get_post_name_from_tax_name( $taxonomy ); -
wicked-folders/trunk/readme.txt
r2805161 r2860994 4 4 Requires at least: 4.6 5 5 Tested up to: 6.1 6 Stable tag: 2.18.1 66 Stable tag: 2.18.17 7 7 License: GPLv2 or later 8 8 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 138 138 == Changelog == 139 139 140 = 2.18.17 (February 6, 2023) = 141 * Add nonce validation to AJAX functions to address cross-site request forgery vulnerability 142 * Add capability check to AJAX functions to address authorization bypass vulnerability 143 140 144 = 2.18.16 (October 26, 2022) = 141 145 * Tested with WordPress 6.1 and updated tested-up-to flag -
wicked-folders/trunk/wicked-folders.php
r2805161 r2860994 5 5 Plugin URI: https://wickedplugins.com/wicked-folders/ 6 6 Description: Organize your pages into folders. 7 Version: 2.18.1 67 Version: 2.18.17 8 8 Author: Wicked Plugins 9 9 Author URI: https://wickedplugins.com/
Note: See TracChangeset
for help on using the changeset viewer.