diff --git a/woo-business-central/admin/class-wbc-admin.php b/woo-business-central/admin/class-wbc-admin.php index 3df3c4c..1161de3 100644 --- a/woo-business-central/admin/class-wbc-admin.php +++ b/woo-business-central/admin/class-wbc-admin.php @@ -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 ); } /** diff --git a/woo-business-central/admin/partials/wbc-admin-display.php b/woo-business-central/admin/partials/wbc-admin-display.php index 7903375..3bef8e9 100644 --- a/woo-business-central/admin/partials/wbc-admin-display.php +++ b/woo-business-central/admin/partials/wbc-admin-display.php @@ -34,7 +34,7 @@ $tabs = array(