fix: client secret getting corrupted on save

Two bugs fixed:

1. sanitize_text_field() was stripping special characters from Azure AD
   client secrets (e.g. %XX sequences, angle brackets). Replaced with
   trim() to preserve the raw secret before encryption.

2. All settings tabs shared one option group (wbc_settings), so saving
   from any tab would trigger sanitize callbacks for ALL settings. This
   caused checkboxes on other tabs to reset to 'no' and could interfere
   with the client secret. Split into per-tab groups: wbc_connection,
   wbc_sync, wbc_orders.

Also clears OAuth token cache when client secret is changed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-17 10:15:07 +01:00
parent b64397dcd3
commit c06d6e4352
2 changed files with 30 additions and 21 deletions

View File

@@ -37,48 +37,49 @@ class WBC_Admin {
}
/**
* Register settings
* Register settings - each tab has its own option group to prevent
* cross-tab overwrites when saving from a single tab.
*/
public function register_settings() {
// Connection settings
register_setting( 'wbc_settings', 'wbc_tenant_id', array(
// Connection settings (own group)
register_setting( 'wbc_connection', 'wbc_tenant_id', array(
'sanitize_callback' => 'sanitize_text_field',
) );
register_setting( 'wbc_settings', 'wbc_client_id', array(
register_setting( 'wbc_connection', 'wbc_client_id', array(
'sanitize_callback' => 'sanitize_text_field',
) );
register_setting( 'wbc_settings', 'wbc_client_secret', array(
register_setting( 'wbc_connection', 'wbc_client_secret', array(
'sanitize_callback' => array( $this, 'sanitize_client_secret' ),
) );
register_setting( 'wbc_settings', 'wbc_environment', array(
register_setting( 'wbc_connection', 'wbc_environment', array(
'sanitize_callback' => 'sanitize_text_field',
) );
register_setting( 'wbc_settings', 'wbc_company_id', array(
register_setting( 'wbc_connection', 'wbc_company_id', array(
'sanitize_callback' => 'sanitize_text_field',
) );
// Sync settings
register_setting( 'wbc_settings', 'wbc_sync_frequency', array(
// Sync settings (own group)
register_setting( 'wbc_sync', 'wbc_sync_frequency', array(
'sanitize_callback' => array( $this, 'sanitize_frequency' ),
) );
register_setting( 'wbc_settings', 'wbc_enable_stock_sync', array(
register_setting( 'wbc_sync', 'wbc_enable_stock_sync', array(
'sanitize_callback' => array( $this, 'sanitize_checkbox' ),
) );
register_setting( 'wbc_settings', 'wbc_enable_price_sync', array(
register_setting( 'wbc_sync', 'wbc_enable_price_sync', array(
'sanitize_callback' => array( $this, 'sanitize_checkbox' ),
) );
// Order settings
register_setting( 'wbc_settings', 'wbc_enable_order_sync', array(
// Order settings (own group)
register_setting( 'wbc_orders', 'wbc_enable_order_sync', array(
'sanitize_callback' => array( $this, 'sanitize_checkbox' ),
) );
register_setting( 'wbc_settings', 'wbc_default_payment_terms_id', array(
register_setting( 'wbc_orders', 'wbc_default_payment_terms_id', array(
'sanitize_callback' => 'sanitize_text_field',
) );
register_setting( 'wbc_settings', 'wbc_default_shipment_method_id', array(
register_setting( 'wbc_orders', 'wbc_default_shipment_method_id', array(
'sanitize_callback' => 'sanitize_text_field',
) );
register_setting( 'wbc_settings', 'wbc_shipping_item_number', array(
register_setting( 'wbc_orders', 'wbc_shipping_item_number', array(
'sanitize_callback' => 'sanitize_text_field',
) );
}
@@ -86,6 +87,9 @@ class WBC_Admin {
/**
* Sanitize client secret
*
* Do NOT use sanitize_text_field() here - it strips characters like %XX
* sequences, angle brackets, etc. that are common in Azure AD client secrets.
*
* @param string $value Input value.
* @return string Sanitized value.
*/
@@ -100,8 +104,13 @@ class WBC_Admin {
return get_option( 'wbc_client_secret', '' );
}
// Encrypt new value
return WBC_OAuth::encrypt( sanitize_text_field( $value ) );
// Only trim whitespace, then encrypt - preserve all secret characters
$value = trim( wp_unslash( $value ) );
// Clear cached OAuth token since secret changed
WBC_OAuth::clear_token_cache();
return WBC_OAuth::encrypt( $value );
}
/**

View File

@@ -34,7 +34,7 @@ $tabs = array(
<?php if ( $current_tab === 'connection' ) : ?>
<!-- Connection Settings -->
<form method="post" action="options.php" class="wbc-settings-form">
<?php settings_fields( 'wbc_settings' ); ?>
<?php settings_fields( 'wbc_connection' ); ?>
<div class="wbc-card">
<h2><?php esc_html_e( 'Microsoft Azure AD Credentials', 'woo-business-central' ); ?></h2>
@@ -141,7 +141,7 @@ $tabs = array(
<?php elseif ( $current_tab === 'sync' ) : ?>
<!-- Sync Settings -->
<form method="post" action="options.php" class="wbc-settings-form">
<?php settings_fields( 'wbc_settings' ); ?>
<?php settings_fields( 'wbc_sync' ); ?>
<div class="wbc-card">
<h2><?php esc_html_e( 'Product Sync Settings', 'woo-business-central' ); ?></h2>
@@ -218,7 +218,7 @@ $tabs = array(
<?php elseif ( $current_tab === 'orders' ) : ?>
<!-- Order Settings -->
<form method="post" action="options.php" class="wbc-settings-form">
<?php settings_fields( 'wbc_settings' ); ?>
<?php settings_fields( 'wbc_orders' ); ?>
<div class="wbc-card">
<h2><?php esc_html_e( 'Order Sync Settings', 'woo-business-central' ); ?></h2>