Fix certificate storage being undone by the settings sanitiser

store_certificate() and remove_certificate() wrote the option with
update_option(), which runs the registered sanitize() callback in the
admin (including admin-ajax). sanitize() expects raw form input, so it
restored the previous certificate fields and encrypted the stored client
secret a second time: "Generate certificate" did not keep the new
certificate and broke an existing client secret.

Internal writes now bypass the form sanitiser.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Friederich Loheide 2026-09-23 16:34:19 +00:00
parent b0b319e73a
commit 1708bae91a

View file

@ -19,6 +19,13 @@ class M365_Login_Settings {
*/ */
private $cache = null; private $cache = null;
/**
* Set while the plugin writes already sanitised values (skips the form sanitiser).
*
* @var bool
*/
private $raw_write = false;
/** /**
* Default settings. * Default settings.
* *
@ -199,8 +206,7 @@ class M365_Login_Settings {
$all = $this->all(); $all = $this->all();
$all['cert_private_key'] = $enc; $all['cert_private_key'] = $enc;
$all['cert_certificate'] = $pair['certificate']; $all['cert_certificate'] = $pair['certificate'];
update_option( M365_LOGIN_OPTION, $all ); $this->write( $all );
$this->cache = null;
return true; return true;
} }
@ -211,7 +217,21 @@ class M365_Login_Settings {
$all = $this->all(); $all = $this->all();
$all['cert_private_key'] = ''; $all['cert_private_key'] = '';
$all['cert_certificate'] = ''; $all['cert_certificate'] = '';
$this->write( $all );
}
/**
* Stores already sanitised settings.
*
* The option is registered with sanitize() as callback, which expects raw form input
* (it would, for example, encrypt the stored client secret a second time).
*
* @param array $all Complete settings.
*/
private function write( $all ) {
$this->raw_write = true;
update_option( M365_LOGIN_OPTION, $all ); update_option( M365_LOGIN_OPTION, $all );
$this->raw_write = false;
$this->cache = null; $this->cache = null;
} }
@ -379,6 +399,10 @@ class M365_Login_Settings {
* @return array * @return array
*/ */
public function sanitize( $input ) { public function sanitize( $input ) {
if ( $this->raw_write ) {
return $input;
}
$defaults = $this->defaults(); $defaults = $this->defaults();
$current = $this->all(); $current = $this->all();
$input = is_array( $input ) ? $input : array(); $input = is_array( $input ) ? $input : array();