Skip to content

Native Users window: profile settings plugins add through core's profile hooks are missing #1020

Open

Description

@juanlentino

Summary

With the native Users window turned on (Preferences, Features, nativeUsersEnabled), the profile in OpenStation leaves out everything plugins add to the profile screen through core's hooks:

  • show_user_profile / edit_user_profile: sections after Application Passwords;
  • personal_options: rows inside the Personal Options table;
  • profile_personal_options: the block right after that table, on your own profile.

Their save hooks, personal_options_update and edit_user_profile_update, never run either. This affects any plugin that adds profile settings this way, for example sign-in security options, author fields or per-user preferences. There is no way to view or change those settings from inside OpenStation. The same profile in classic admin shows them.

The User Edit window and the Users window's Profile tab both render <os-user-profile>, which loads and saves the core fields through wp/v2/users/<id>.

With the native Users window turned off (the default), profile.php opens in an iframe window and everything works.

Environment

  • WordPress 7.1.3, PHP 8.3
  • OpenStation 1.1.15 (trunk at the v1.1.15 tag)
  • Chromium-based browser
  • Local site run with WordPress Playground CLI 3.1.58 (Docker was not available for wp-env on this machine)

Steps to reproduce

  1. Add this mu-plugin. It uses only core hooks:
<?php
add_action( 'show_user_profile', 'repro_profile_field' );
add_action( 'edit_user_profile', 'repro_profile_field' );
function repro_profile_field( $user ) {
	echo '<h2>Repro section</h2><table class="form-table"><tr><th><label for="repro_field">Repro field</label></th><td><input type="text" name="repro_field" id="repro_field" value="' . esc_attr( get_user_meta( $user->ID, 'repro_field', true ) ) . '" /></td></tr></table>';
}
add_action( 'personal_options', function ( $user ) {
	echo '<tr><th><label for="repro_row">Repro row</label></th><td><input type="text" name="repro_row" id="repro_row" value="' . esc_attr( get_user_meta( $user->ID, 'repro_row', true ) ) . '" /></td></tr>';
} );
add_action( 'profile_personal_options', function () {
	echo '<h2>Repro block</h2><p>Printed on profile_personal_options.</p>';
} );
add_action( 'personal_options_update', 'repro_profile_field_save' );
add_action( 'edit_user_profile_update', 'repro_profile_field_save' );
function repro_profile_field_save( $user_id ) {
	if ( ! current_user_can( 'edit_user', $user_id ) ) {
		return;
	}
	foreach ( array( 'repro_field', 'repro_row' ) as $key ) {
		if ( isset( $_POST[ $key ] ) ) {
			update_user_meta( $user_id, $key, sanitize_text_field( wp_unslash( $_POST[ $key ] ) ) );
		}
	}
}
  1. Open OpenStation and turn on the native Users window in Preferences, Features.
  2. Open Profile from the dock (Users, Profile), or load /wp-admin/profile.php directly.

Expected

The profile shows "Repro row", "Repro block" and "Repro section", and saving them works, as on the classic profile.php.

Actual

The native Edit user window (and the Users window's Profile tab) shows only the core fields. None of the three is present. Loading /wp-admin/profile.php directly opens the same native window. Editing another user in the native window is affected the same way (edit_user_profile).

What I checked

Case Result
Classic admin (profile.php?desktop_mode_classic=1) All plugin output renders; saving persists
OpenStation, native Users off, Profile from the dock profile.php in an iframe window; all plugin output renders; saving persists
OpenStation, native Users off, /wp-admin/profile.php directly Same as above
OpenStation, native Users on, Profile from the dock Native Edit user window; no plugin output
OpenStation, native Users on, /wp-admin/profile.php directly Native Edit user window; no plugin output

I also checked a plugin section that sends the user through wp-login.php to re-authenticate and back to profile.php#anchor before its options can be changed. That round trip works in classic admin and in an iframe window. In the native window it cannot be reached because the section is not there.

Returning false from openstation_user_edit_window_user_can_register does not bring the classic screen back for profile.php: the Users window still claims profile.php through its Profile tab, which renders the same element.

I did not find a security impact. The native form only saves core fields through core's REST controller, and a plugin's own checks still apply to its settings.

Cause

apps/users/profile/ (<os-user-profile>) builds a fixed form and saves through PUT wp/v2/users/<id> (apps/users/profile/client.ts). None of show_user_profile, edit_user_profile, personal_options, profile_personal_options, personal_options_update or edit_user_profile_update is called anywhere in OpenStation. The plugins' output also depends on scripts they enqueue for profile.php and on core's form post, so it cannot be rebuilt from REST data.

Activity

  1. changed the title [-]Native Users window: profile sections added by other plugins (show_user_profile / edit_user_profile) are missing[/-] [+]Native Users window: profile settings plugins add through core's profile hooks are missing[/+] on Oct 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions