diff --git a/README.md b/README.md index c2ac19528..7461fc88f 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ **Requires at least:** 5.6 **Requires PHP:** 7.4 **Tested up to:** 7.1 -**Stable tag:** 2.20.4 +**Stable tag:** 2.20.5 **License:** GPLv2 or later **License URI:** https://www.gnu.org/licenses/gpl-2.0.html @@ -124,6 +124,10 @@ Our external packages use [Rating Star Component](https://github.com/n49/react-s Spectra Legacy receives maintenance updates only: security fixes, WordPress and PHP compatibility, and critical bug fixes. New features ship in Spectra Blocks. +### 2.20.5 - Friday, 9th October 2026 ### +* Fix: This update addressed a security bug. Props to Wordfence for reporting it responsibly to our team. Please make sure you are using the latest version on your website. +* Fix: Resolved an issue where changing the site address could cause plugin assets to be rebuilt on every page load. + ### 2.20.4 - Monday, 28th September 2026 ### * Fix: This update addressed a security bug. Props to Wordfence for reporting it responsibly to our team. Please make sure you are using the latest version on your website. * Fix: Resolved a performance issue where saving navigation menus could trigger unnecessary asset cache regeneration. diff --git a/admin-core/ajax/common-settings.php b/admin-core/ajax/common-settings.php index 0b8195ba9..3fa6213a7 100644 --- a/admin-core/ajax/common-settings.php +++ b/admin-core/ajax/common-settings.php @@ -386,6 +386,28 @@ public function load_select_font_globally() { $this->save_admin_settings( 'uag_load_select_font_globally', sanitize_text_field( $value ) ); } + /** + * Resync the FSE theme fonts after a font setting changes. + * + * The font-file deletion and theme.json rewrite live in + * UAGB_FSE_Fonts_Compatibility. Running it here keeps the sync inside this + * capability-and-nonce-checked handler, rather than the former + * unauthenticated GET request. + * + * @since 2.20.5 + * @return void + */ + private function sync_fse_theme_fonts() { + if ( ! class_exists( 'UAGB_FSE_Fonts_Compatibility' ) ) { + return; + } + + $fse_fonts = \UAGB_FSE_Fonts_Compatibility::get_instance(); + if ( $fse_fonts instanceof \UAGB_FSE_Fonts_Compatibility ) { + $fse_fonts->sync_theme_fonts(); + } + } + /** * Save setting - Loads selected font globally. * @@ -395,7 +417,9 @@ public function load_select_font_globally() { public function load_fse_font_globally() { $this->check_permission_nonce( 'uag_load_fse_font_globally' ); $value = $this->check_post_value(); - $this->save_admin_settings( 'uag_load_fse_font_globally', sanitize_text_field( $value ) ); + \UAGB_Admin_Helper::update_admin_settings_option( 'uag_load_fse_font_globally', sanitize_text_field( $value ) ); + $this->sync_fse_theme_fonts(); + wp_send_json_success( array( 'messsage' => __( 'Successfully saved data!', 'ultimate-addons-for-gutenberg' ) ) ); } /** @@ -460,7 +484,9 @@ public function fse_font_globally() { $spectra_global_fse_fonts[] = $value; - $this->save_admin_settings( 'spectra_global_fse_fonts', $this->sanitize_form_inputs( $spectra_global_fse_fonts ) ); + \UAGB_Admin_Helper::update_admin_settings_option( 'spectra_global_fse_fonts', $this->sanitize_form_inputs( $spectra_global_fse_fonts ) ); + $this->sync_fse_theme_fonts(); + wp_send_json_success( array( 'messsage' => __( 'Successfully saved data!', 'ultimate-addons-for-gutenberg' ) ) ); } /** diff --git a/admin-core/inc/admin-menu.php b/admin-core/inc/admin-menu.php index 28be4bef4..9bf24e991 100644 --- a/admin-core/inc/admin-menu.php +++ b/admin-core/inc/admin-menu.php @@ -543,6 +543,7 @@ public function styles_scripts() { 'plugin_manager_nonce' => wp_create_nonce( 'spectra_plugin_manager_nonce' ), 'installer_nonce' => wp_create_nonce( 'updates' ), 'force_check_plugin_updates_nonce' => wp_create_nonce( 'uag_force_check_plugin_updates' ), + 'fse_fonts_sync_nonce' => wp_create_nonce( 'uagb_fse_fonts_sync' ), 'pro_installed_status' => 'inactive' === self::get_plugin_status( 'spectra-pro/spectra-pro.php' ) ? true : false, 'pro_plugin_status' => self::get_plugin_status( 'spectra-pro/spectra-pro.php' ), 'contry_code' => \UAGB_Admin_Helper::get_user_country_code(), diff --git a/classes/class-uagb-fse-fonts-compatibility.php b/classes/class-uagb-fse-fonts-compatibility.php index eca82086f..39dd07418 100644 --- a/classes/class-uagb-fse-fonts-compatibility.php +++ b/classes/class-uagb-fse-fonts-compatibility.php @@ -90,15 +90,42 @@ public function __construct() { $this->base_url = UAGB_UPLOAD_URL . 'assets/'; - if ( empty( $_GET['page'] ) || 'spectra' !== $_GET['page'] || empty( $_GET['path'] ) || 'settings' !== $_GET['path'] || empty( $_GET['settings'] ) || 'fse-support' !== $_GET['settings'] ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended -- $_GET['settings'] does not provide nonce. + // Carry the globally selected FSE fonts into a newly activated theme. + // Fonts live in each theme's own theme.json, so switching themes would + // otherwise leave them behind in the previous theme. Theme switching is + // an admin-only, nonce-protected action, so this is a safe trigger. + add_action( 'after_switch_theme', array( $this, 'sync_fonts_on_theme_switch' ) ); + + if ( empty( $_GET['page'] ) || 'spectra' !== $_GET['page'] || empty( $_GET['path'] ) || 'settings' !== $_GET['path'] || empty( $_GET['settings'] ) || 'fse-support' !== $_GET['settings'] ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Routing check only; the nonce is verified below before any action runs. return; } - // Bail if the request is not from a logged-in admin. This routine deletes theme font files and rewrites theme.json, so it must never run for unauthenticated or unprivileged visitors. + // Verify the nonce first. This routine deletes theme font files and rewrites theme.json, so a forged GET link — even one a logged-in admin is tricked into clicking — must be rejected before anything else. Only the Spectra dashboard mints this nonce, so a capability check alone cannot stop the CSRF. + $fse_sync_nonce = isset( $_GET['_wpnonce'] ) ? sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) ) : ''; + if ( ! wp_verify_nonce( $fse_sync_nonce, 'uagb_fse_fonts_sync' ) ) { + return; + } + + // Then require an administrator: the routine must never run for unprivileged users even with a valid nonce. if ( ! is_admin() || ! current_user_can( 'manage_options' ) ) { return; } + $this->sync_theme_fonts(); + } + + /** + * Delete the theme's Spectra fonts and resync them from the saved global list. + * + * Called by the capability-and-nonce-checked dashboard AJAX handlers after a + * font setting changes, and by the nonce-protected GET handler, so the font + * files and theme.json stay in step with the Spectra dashboard. Must only be + * reached from those authorized admin contexts. + * + * @since 2.20.5 + * @return void + */ + public function sync_theme_fonts() { $uagb_filesystem = uagb_filesystem(); $fonts_folder_path = get_stylesheet_directory() . '/assets/fonts/spectra'; @@ -108,11 +135,24 @@ public function __construct() { self::delete_all_theme_font_family(); - $load_fse_font_globally = UAGB_Admin_Helper::get_admin_settings_option( 'uag_load_fse_font_globally', 'disabled' ); - - if ( 'disabled' !== $load_fse_font_globally ) { + if ( 'disabled' !== UAGB_Admin_Helper::get_admin_settings_option( 'uag_load_fse_font_globally', 'disabled' ) ) { + $this->save_google_fonts_to_theme(); + } + } - add_action( 'admin_init', array( $this, 'save_google_fonts_to_theme' ) ); + /** + * Resync the global FSE fonts into the theme that was just activated. + * + * Hooked on after_switch_theme so the admin's selected fonts follow the + * active theme. Skipped entirely when the feature is off, to avoid touching + * the new theme's theme.json. + * + * @since 2.20.5 + * @return void + */ + public function sync_fonts_on_theme_switch() { + if ( 'disabled' !== UAGB_Admin_Helper::get_admin_settings_option( 'uag_load_fse_font_globally', 'disabled' ) ) { + $this->sync_theme_fonts(); } } diff --git a/classes/class-uagb-loader.php b/classes/class-uagb-loader.php index 52a862a1d..21507ab40 100644 --- a/classes/class-uagb-loader.php +++ b/classes/class-uagb-loader.php @@ -140,7 +140,7 @@ public function define_constants() { define( 'UAGB_BASE', plugin_basename( UAGB_FILE ) ); define( 'UAGB_DIR', plugin_dir_path( UAGB_FILE ) ); define( 'UAGB_URL', plugins_url( '/', UAGB_FILE ) ); - define( 'UAGB_VER', '2.20.4' ); + define( 'UAGB_VER', '2.20.5' ); define( 'UAGB_MODULES_DIR', UAGB_DIR . 'modules/' ); define( 'UAGB_MODULES_URL', UAGB_URL . 'modules/' ); define( 'UAGB_SLUG', 'spectra' ); @@ -642,9 +642,18 @@ public function get_regenerate_assets_on_migration() { return; } - // If the stored domain is different from the current site domain, update the '__uagb_asset_version' option with the current timestamp. + // If the stored domain is different from the current site domain, bump the + // asset version ONCE for the migration and persist the new domain so the + // two reconcile. Previously only the version was bumped and 'uagb_site_url' + // was never updated, so the domains never matched again: every subsequent + // request re-entered this branch, bumped '__uagb_asset_version' to a fresh + // timestamp, and forced every page to rebuild its assets on every view. + // That perpetual regeneration is what deadlocks the concurrent + // delete_post_meta() calls in UAGB_Post_Assets::allow_assets_generation() + // under load (#6095). if ( $stored_domain !== $site_domain ) { \UAGB_Admin_Helper::update_admin_settings_option( '__uagb_asset_version', time() ); + \UAGB_Admin_Helper::update_admin_settings_option( 'uagb_site_url', $site_domain ); } } diff --git a/languages/ultimate-addons-for-gutenberg.pot b/languages/ultimate-addons-for-gutenberg.pot index 6d1c8b90e..4fc9833ba 100644 --- a/languages/ultimate-addons-for-gutenberg.pot +++ b/languages/ultimate-addons-for-gutenberg.pot @@ -2,7 +2,7 @@ # This file is distributed under the same license as the Spectra plugin. msgid "" msgstr "" -"Project-Id-Version: Spectra 2.20.4\n" +"Project-Id-Version: Spectra 2.20.5\n" "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/ultimate-addons-for-gutenberg\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/package-lock.json b/package-lock.json index aaefc43fb..9300b3b6a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ultimate-addons-for-gutenberg", - "version": "2.20.4", + "version": "2.20.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ultimate-addons-for-gutenberg", - "version": "2.20.4", + "version": "2.20.5", "license": "ISC", "dependencies": { "@bsf/force-ui": "git+https://github.com/brainstormforce/bsf-admin-ui#v1.7.7", diff --git a/package.json b/package.json index 5775b7ff8..fc8092468 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ultimate-addons-for-gutenberg", - "version": "2.20.4", + "version": "2.20.5", "description": "The Ultimate Addons for Gutenberg extends the Gutenberg functionality with several unique and feature-rich blocks that help build websites faster.", "author": "Brainstorm Force", "license": "ISC", diff --git a/readme.txt b/readme.txt index 02ce49a16..e4ab3401d 100644 --- a/readme.txt +++ b/readme.txt @@ -5,7 +5,7 @@ Tags: gutenberg, blocks, gutenberg blocks, editor, block Requires at least: 5.6 Requires PHP: 7.4 Tested up to: 7.1 -Stable tag: 2.20.4 +Stable tag: 2.20.5 License: GPLv2 or later License URI: https://www.gnu.org/licenses/gpl-2.0.html @@ -124,6 +124,10 @@ Our external packages use [Rating Star Component](https://github.com/n49/react-s Spectra Legacy receives maintenance updates only: security fixes, WordPress and PHP compatibility, and critical bug fixes. New features ship in Spectra Blocks. += 2.20.5 - Friday, 9th October 2026 = +* Fix: This update addressed a security bug. Props to Wordfence for reporting it responsibly to our team. Please make sure you are using the latest version on your website. +* Fix: Resolved an issue where changing the site address could cause plugin assets to be rebuilt on every page load. + = 2.20.4 - Monday, 28th September 2026 = * Fix: This update addressed a security bug. Props to Wordfence for reporting it responsibly to our team. Please make sure you are using the latest version on your website. * Fix: Resolved a performance issue where saving navigation menus could trigger unnecessary asset cache regeneration. diff --git a/ultimate-addons-for-gutenberg.php b/ultimate-addons-for-gutenberg.php index 6f5aa743b..68d691532 100644 --- a/ultimate-addons-for-gutenberg.php +++ b/ultimate-addons-for-gutenberg.php @@ -4,7 +4,7 @@ * Plugin URI: https://www.brainstormforce.com * Author: Brainstorm Force * Author URI: https://www.brainstormforce.com - * Version: 2.20.4 + * Version: 2.20.5 * Description: The Spectra extends the Gutenberg functionality with several unique and feature-rich blocks that help build websites faster. * Text Domain: ultimate-addons-for-gutenberg * Domain Path: /languages