diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a71e4f95e..540f565275 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,13 +4,15 @@ All notable changes to this project will be documented in this file, per [the Ke ## [Unreleased] +### Security +* Hide the Subscription Token value in the Settings page. Props [@faisalahammad](https://github.com/faisalahammad) via [#4324](https://github.com/10up/ElasticPress/pull/4324). + diff --git a/includes/classes/Screen/Settings.php b/includes/classes/Screen/Settings.php index 0e1dacf6ac..dfb47c3fec 100644 --- a/includes/classes/Screen/Settings.php +++ b/includes/classes/Screen/Settings.php @@ -97,11 +97,13 @@ public function action_admin_init() { Utils\update_option( 'ep_host', $host ); } - if ( isset( $post['ep_credentials'] ) ) { - $credentials = ( isset( $post['ep_credentials'] ) ) ? Utils\sanitize_credentials( $post['ep_credentials'] ) : [ - 'username' => '', - 'token' => '', - ]; + if ( isset( $post['ep_credentials'] ) && ( ! defined( 'EP_CREDENTIALS' ) || ! EP_CREDENTIALS ) ) { + $credentials = Utils\sanitize_credentials( $post['ep_credentials'] ); + + // Preserve the existing token if the field was left empty (it is always empty on load). + if ( empty( $credentials['token'] ) ) { + $credentials['token'] = $this->prev_ep_credentials['token']; + } Utils\update_option( 'ep_credentials', $credentials ); } diff --git a/includes/partials/settings-page.php b/includes/partials/settings-page.php index 41e44b9dfa..6eadfc461f 100644 --- a/includes/partials/settings-page.php +++ b/includes/partials/settings-page.php @@ -134,12 +134,12 @@ */ if ( apply_filters( 'ep_admin_show_credentials', true ) ) : ?> - disabled type="text" value="" name="ep_credentials[token]" id="ep_token"> + disabled type="password" value="" autocomplete="new-password" placeholder="" name="ep_credentials[token]" id="ep_token">
- + diff --git a/tests/php/screen/TestSettings.php b/tests/php/screen/TestSettings.php index 11ed3032f1..30affd4913 100644 --- a/tests/php/screen/TestSettings.php +++ b/tests/php/screen/TestSettings.php @@ -108,6 +108,95 @@ public function test_action_admin_init_wrong_host() { $this->assertNotContains( 'ep_host', $_POST ); } + /** + * Test that an empty token in POST preserves the stored token. + * + * The token field is always empty on page load, so a save without a new + * value must not wipe the existing token. + * + * @group screen + * @group settings-screen + */ + public function test_action_admin_init_empty_token_preserves_stored_token() { + global $_POST; + + if ( defined( 'EP_CREDENTIALS' ) && EP_CREDENTIALS ) { + $this->markTestSkipped( 'EP_CREDENTIALS constant overrides the option.' ); + } + + // Make is_epio() true so get_epio_credentials() reads the option. + putenv( 'IS_EPIO_ENVIRONMENT=1' ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.runtime_configuration_putenv + + $settings = new Settings(); + + Utils\update_option( + 'ep_credentials', + [ + 'username' => 'u', + 'token' => 'secret', + ] + ); + + $_POST = [ + 'ep_settings_nonce' => wp_create_nonce( 'elasticpress_settings' ), + 'ep_language' => 'site-default', + 'ep_host' => Utils\get_host(), + 'ep_credentials' => [ + 'username' => 'u', + 'token' => '', + ], + ]; + + $settings->action_admin_init(); + + $this->assertSame( 'secret', Utils\get_option( 'ep_credentials' )['token'] ); + + putenv( 'IS_EPIO_ENVIRONMENT' ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.runtime_configuration_putenv + } + + /** + * Test that a new token value is saved. + * + * @group screen + * @group settings-screen + */ + public function test_action_admin_init_new_token_is_saved() { + global $_POST; + + if ( defined( 'EP_CREDENTIALS' ) && EP_CREDENTIALS ) { + $this->markTestSkipped( 'EP_CREDENTIALS constant overrides the option.' ); + } + + // Make is_epio() true so get_epio_credentials() reads the option. + putenv( 'IS_EPIO_ENVIRONMENT=1' ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.runtime_configuration_putenv + + $settings = new Settings(); + + Utils\update_option( + 'ep_credentials', + [ + 'username' => 'u', + 'token' => 'old', + ] + ); + + $_POST = [ + 'ep_settings_nonce' => wp_create_nonce( 'elasticpress_settings' ), + 'ep_language' => 'site-default', + 'ep_host' => Utils\get_host(), + 'ep_credentials' => [ + 'username' => 'u', + 'token' => 'new-token', + ], + ]; + + $settings->action_admin_init(); + + $this->assertSame( 'new-token', Utils\get_option( 'ep_credentials' )['token'] ); + + putenv( 'IS_EPIO_ENVIRONMENT' ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.runtime_configuration_putenv + } + /** * Test the `add_validation_notice` method *