Make WordPress Core

Changeset 54122


Ignore:
Timestamp:
09/11/2022 08:44:50 PM (20 months ago)
Author:
joemcgill
Message:

Editor: Refresh nones for metaboxes after reauthentication.

This fixes an issue where metaboxes fail to save after a session expires and a user logs in again via the heartbeat API.

Props LinSoftware.
Fixes #52584.

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/includes/admin-filters.php

    r54094 r54122  
    8181
    8282add_filter( 'wp_refresh_nonces', 'wp_refresh_post_nonces', 10, 3 );
     83add_filter( 'wp_refresh_nonces', 'wp_refresh_metabox_loader_nonces', 10, 2 );
    8384add_filter( 'wp_refresh_nonces', 'wp_refresh_heartbeat_nonces' );
    8485
  • trunk/src/wp-admin/includes/misc.php

    r54071 r54122  
    12571257
    12581258/**
     1259 * Refresh nonces used with meta boxes in the block editor.
     1260 *
     1261 * @since 6.1.0
     1262 *
     1263 * @param array  $response  The Heartbeat response.
     1264 * @param array  $data      The $_POST data sent.
     1265 * @return array The Heartbeat response.
     1266 */
     1267function wp_refresh_metabox_loader_nonces( $response, $data ) {
     1268    if ( empty( $data['wp-refresh-metabox-loader-nonces'] ) ) {
     1269        return $response;
     1270    }
     1271
     1272    $received = $data['wp-refresh-metabox-loader-nonces'];
     1273    $post_id  = (int) $received['post_id'];
     1274
     1275    if ( ! $post_id ) {
     1276        return $response;
     1277    }
     1278
     1279    if ( ! current_user_can( 'edit_post', $post_id ) ) {
     1280        return $response;
     1281    }
     1282
     1283    $response['wp-refresh-metabox-loader-nonces'] = array(
     1284        'replace' => array(
     1285            'metabox_loader_nonce' => wp_create_nonce( 'meta-box-loader' ),
     1286            '_wpnonce'             => wp_create_nonce( 'update-post_' . $post_id ),
     1287        ),
     1288    );
     1289
     1290    return $response;
     1291}
     1292
     1293/**
    12591294 * Adds the latest Heartbeat and REST-API nonce to the Heartbeat response.
    12601295 *
  • trunk/src/wp-admin/includes/post.php

    r53715 r54122  
    23352335    }
    23362336
     2337    /*
     2338     * Refresh nonces used by the meta box loader.
     2339     *
     2340     * The logic is very similar to that provided by post.js for the classic editor.
     2341     */
     2342    $script = "( function( $ ) {
     2343        var check, timeout;
     2344
     2345        function schedule() {
     2346            check = false;
     2347            window.clearTimeout( timeout );
     2348            timeout = window.setTimeout( function() { check = true; }, 300000 );
     2349        }
     2350
     2351        $( document ).on( 'heartbeat-send.wp-refresh-nonces', function( e, data ) {
     2352            var post_id, \$authCheck = $( '#wp-auth-check-wrap' );
     2353
     2354            if ( check || ( \$authCheck.length && ! \$authCheck.hasClass( 'hidden' ) ) ) {
     2355                if ( ( post_id = $( '#post_ID' ).val() ) && $( '#_wpnonce' ).val() ) {
     2356                    data['wp-refresh-metabox-loader-nonces'] = {
     2357                        post_id: post_id
     2358                    };
     2359                }
     2360            }
     2361        }).on( 'heartbeat-tick.wp-refresh-nonces', function( e, data ) {
     2362            var nonces = data['wp-refresh-metabox-loader-nonces'];
     2363
     2364            if ( nonces ) {
     2365                if ( nonces.replace ) {
     2366                    if ( nonces.replace.metabox_loader_nonce && window._wpMetaBoxUrl && wp.url ) {
     2367                        window._wpMetaBoxUrl= wp.url.addQueryArgs( window._wpMetaBoxUrl, { 'meta-box-loader-nonce': nonces.replace.metabox_loader_nonce } );
     2368                    }
     2369
     2370                    if ( nonces.replace._wpnonce ) {
     2371                        $( '#_wpnonce' ).val( nonces.replace._wpnonce );
     2372                    }
     2373                }
     2374            }
     2375        }).ready( function() {
     2376            schedule();
     2377        });
     2378    } )( jQuery );";
     2379    wp_add_inline_script( 'heartbeat', $script );
     2380
    23372381    // Reset meta box data.
    23382382    $wp_meta_boxes = $_original_meta_boxes;
  • trunk/tests/phpunit/tests/admin/includesPost.php

    r53572 r54122  
    10171017        $this->assertSame( 0, post_exists( $title, null, null, 'wp_tests', $post_status ) );
    10181018    }
     1019
     1020    /**
     1021     * Test refreshed nonce for metabox loader.
     1022     *
     1023     * @return void
     1024     */
     1025    public function test_user_get_refreshed_metabox_nonce() {
     1026
     1027        // Create a post by the current user.
     1028        wp_set_current_user( self::$editor_id );
     1029
     1030        $post_data = array(
     1031            'post_content' => 'Test post content',
     1032            'post_title'   => 'Test post title',
     1033            'post_excerpt' => 'Test post excerpt',
     1034            'post_author'  => self::$editor_id,
     1035            'post_status'  => 'draft',
     1036        );
     1037        $post_id   = wp_insert_post( $post_data );
     1038
     1039        // Simulate the $_POST data from the heartbeat.
     1040        $data = array(
     1041            'wp-refresh-metabox-loader-nonces' => array(
     1042                'post_id' => (string) $post_id,
     1043            ),
     1044            'wp-refresh-post-lock'             => array(
     1045                'lock'    => '1658203298:1',
     1046                'post_id' => (string) $post_id,
     1047            ),
     1048        );
     1049
     1050        // Call the function we're testing.
     1051        $response = wp_refresh_metabox_loader_nonces( array(), $data );
     1052
     1053        // Ensure that both nonces were created.
     1054        $this->assertNotEmpty( $response['wp-refresh-metabox-loader-nonces']['replace']['_wpnonce'] );
     1055        $this->assertNotEmpty( $response['wp-refresh-metabox-loader-nonces']['replace']['metabox_loader_nonce'] );
     1056    }
    10191057}
Note: See TracChangeset for help on using the changeset viewer.