Make WordPress Core

Opened 11 months ago

Last modified 8 months ago

#52584 new defect (bug)

Editor: Metaboxes fail to save after heartbeat reauthentication in block editor

Reported by: LinSoftware Owned by:
Milestone: Future Release Priority: normal
Severity: normal Version: 5.0
Component: Editor Keywords: has-patch needs-unit-tests
Focuses: Cc:


When a session expires and a user logs in again via the heartbeat API, the nonces used by the metabox loader are not refreshed. This can cause data loss because saving the metaboxes fails after reauthentication.

Steps to reproduce:

  1. Add a metabox to a post type that uses the block editor. For example:

function wporg_add_custom_box() {
         'Meta Box Test',
         function( $post ) {
            $value = get_post_meta( $post->ID, '_wporg_meta_key', true );
            <label for="wporg_field">Test metabox</label>
            <textarea id="wporg_field" name="wporg_field" rows="4" cols="50"><?php echo esc_html( $value ); ?></textarea>
add_action( 'add_meta_boxes', 'wporg_add_custom_box' );
function wporg_save_postdata( $post_id ) {
   if ( array_key_exists( 'wporg_field', $_POST ) ) {
add_action( 'save_post', 'wporg_save_postdata' );
  1. Edit a post. Change the content in the metabox.
  2. Simulate the session expiring by deleting the site cookies, or in another tab, log out of the site.
  3. On the post edit screen, wait up to 30 seconds for the heartbeat API to cause the authentication modal to appear.
  4. Log in via the authentication modal.
  5. Save or publish your post. The block editor content will successfully save but the content in metaboxes will not. If you clicked “update”, you will see that the button changes to “Updating...” and stays in that state.  Checking the console, you will see errors. If you reload the post edit screen, your metabox changes will be gone. If you tried to publish, it will appear successful, but the metabox data does not get saved.

In the classic editor, post.js was responsible for applying refreshed nonces supplied by wp_refresh_post_nonces(), but that file is not enqueued in the block editor. The attached patch would re-implement the relevant parts of post.js as part of loading metaboxes in the block editor, and it would create a new PHP callback responsible for creating the nonces.

It would also be possible to extract the heartbeat logic out of post.js into a new JS file enqueued by both the classic and block editor screens rather than use the inline JS approach used in the patch. That would widen the scope of the patch, though, and seemed not worth trying without a consensus that it was necessary.

Thanks to @dlh who helped with creating the attached patch.

Attachments (1)

nonces.diff (3.6 KB) - added by LinSoftware 11 months ago.

Download all attachments as: .zip

Change History (6)

11 months ago

#1 @LinSoftware
11 months ago

  • Version changed from 5.6.1 to 5.0

This ticket was mentioned in Slack in #core by linsoftware. View the logs.

11 months ago

#3 @SergeyBiryukov
11 months ago

  • Milestone changed from Awaiting Review to 5.8

This ticket was mentioned in Slack in #core by chaion07. View the logs.

8 months ago

#5 @chaion07
8 months ago

  • Keywords needs-unit-tests added
  • Milestone changed from 5.8 to Future Release

Thanks to @LinSoftware for reporting this. We recently reviewed this during a recent [bug-scrub session]https://wordpress.slack.com/archives/C02RQBWTW/p1623098539375400. Upon consultation with the team and with Beta 1 coming up in a day this could be a good candidate for future Releases. We also noticed that it lacks Unit Testing. So keyword has been added along with milestone being updated. Thanks

Props to @jorbin

Note: See TracTickets for help on using tickets.