| @@ -34,9 +34,9 @@ | ||
| 34 | 34 | * Public static variable to hold the current plugin version. |
| 35 | 35 | * |
| 36 | 36 | * @var string Current plugin version. |
| 37 | 37 | */ |
| 38 | - public static $version = '6.2.3'; // NOSONAR. | |
| 38 | + public static $version = '6.3'; // NOSONAR. | |
| 39 | 39 | |
| 40 | 40 | /** |
| 41 | 41 | * Private static variable to hold the single instance of the class. |
| 42 | 42 | * |
| @@ -290,8 +290,9 @@ | ||
| 290 | 290 | MainWP_Themes::init(); |
| 291 | 291 | MainWP_Plugins::init(); |
| 292 | 292 | MainWP_Updates_Overview::init(); |
| 293 | 293 | MainWP_Client::init(); |
| 294 | + MainWP_Knowledge_UI::init(); | |
| 294 | 295 | MainWP_Rest_Api_Page::init(); |
| 295 | 296 | MainWP_Logger::instance(); |
| 296 | 297 | |
| 297 | 298 | if ( class_exists( '\MainWP\Dashboard\Module\Log\Log_Manage_Insights_Events_Page' ) ) { |
| @@ -617,9 +618,9 @@ | ||
| 617 | 618 | */ |
| 618 | 619 | public static function is_mainwp_site_page() { |
| 619 | 620 | $is_page = false; |
| 620 | 621 | //phpcs:disable WordPress.Security.NonceVerification.Recommended |
| 621 | - if ( isset( $_GET['page'] ) && 'CostTrackerAdd' !== $_GET['page'] && ( ( ( isset( $_GET['id'] ) && ! empty( $_GET['id'] ) ) || ( isset( $_GET['dashboard'] ) && ! empty( $_GET['dashboard'] ) ) || ( isset( $_GET['updateid'] ) && ! empty( $_GET['updateid'] ) ) || ( isset( $_GET['monitor_wpid'] ) && ! empty( $_GET['monitor_wpid'] ) ) || ( isset( $_GET['emailsettingsid'] ) && ! empty( $_GET['emailsettingsid'] ) ) || ( isset( $_GET['scanid'] ) && ! empty( $_GET['scanid'] ) ) ) || ( 'ServerInformation' === $_GET['page'] || 'ServerInformationCron' === $_GET['page'] || 'ErrorLog' === $_GET['page'] || 'ActionLogs' === $_GET['page'] || 'PluginPrivacy' === $_GET['page'] || 'Settings' === $_GET['page'] || 'SettingsAdvanced' === $_GET['page'] || 'SettingsEmail' === $_GET['page'] || 'PremiumUpdates' === $_GET['page'] || 'MainWPTools' === $_GET['page'] || 'SettingsInsights' === $_GET['page'] || 'SettingsApiBackups' === $_GET['page'] || 'MonitoringSettings' === $_GET['page'] ) ) ) { | |
| 622 | + if ( isset( $_GET['page'] ) && 'CostTrackerAdd' !== $_GET['page'] && ( ( ( isset( $_GET['id'] ) && ! empty( $_GET['id'] ) ) || ( isset( $_GET['dashboard'] ) && ! empty( $_GET['dashboard'] ) ) || ( isset( $_GET['knowledgeid'] ) && ! empty( $_GET['knowledgeid'] ) ) || ( isset( $_GET['updateid'] ) && ! empty( $_GET['updateid'] ) ) || ( isset( $_GET['monitor_wpid'] ) && ! empty( $_GET['monitor_wpid'] ) ) || ( isset( $_GET['emailsettingsid'] ) && ! empty( $_GET['emailsettingsid'] ) ) || ( isset( $_GET['scanid'] ) && ! empty( $_GET['scanid'] ) ) ) || ( 'ServerInformation' === $_GET['page'] || 'ServerInformationCron' === $_GET['page'] || 'ErrorLog' === $_GET['page'] || 'ActionLogs' === $_GET['page'] || 'PluginPrivacy' === $_GET['page'] || 'Settings' === $_GET['page'] || 'SettingsAdvanced' === $_GET['page'] || 'SettingsEmail' === $_GET['page'] || 'PremiumUpdates' === $_GET['page'] || 'MainWPTools' === $_GET['page'] || 'SettingsInsights' === $_GET['page'] || 'SettingsApiBackups' === $_GET['page'] || 'MonitoringSettings' === $_GET['page'] ) ) ) { | |
| 622 | 623 | $is_page = true; |
| 623 | 624 | } |
| 624 | 625 | //phpcs:enable |
| 625 | 626 | |
| @@ -732,17 +733,16 @@ | ||
| 732 | 733 | */ |
| 733 | 734 | public function parse_init() { |
| 734 | 735 | // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized |
| 735 | 736 | if ( isset( $_GET['mwpdl'] ) && isset( $_GET['sig'] ) ) { |
| 737 | + if ( ! isset( $_REQUEST['mwpdl'] ) || ! is_string( $_REQUEST['mwpdl'] ) || ! is_string( $_GET['sig'] ) ) { | |
| 738 | + return; | |
| 739 | + } | |
| 736 | 740 | $mwpDir = MainWP_System_Utility::get_mainwp_dir(); |
| 737 | 741 | $mwpDir = $mwpDir[0]; |
| 738 | 742 | $mwpdl = isset( $_REQUEST['mwpdl'] ) ? wp_unslash( $_REQUEST['mwpdl'] ) : ''; |
| 739 | 743 | $file = trailingslashit( $mwpDir ) . rawurldecode( $mwpdl ); |
| 740 | 744 | |
| 741 | - if ( stristr( rawurldecode( $mwpdl ), '..' ) ) { | |
| 742 | - return; | |
| 743 | - } | |
| 744 | - | |
| 745 | 745 | $hasWPFileSystem = MainWP_System_Utility::get_wp_file_system(); |
| 746 | 746 | |
| 747 | 747 | /** |
| 748 | 748 | * WordPress files system object. |
| @@ -750,18 +750,19 @@ | ||
| 750 | 750 | * @global object |
| 751 | 751 | */ |
| 752 | 752 | global $wp_filesystem; |
| 753 | 753 | $sig_value = wp_unslash( $_GET['sig'] ); |
| 754 | - $valid_sig = MainWP_System_Utility::valid_download_sig( $file, $sig_value ); | |
| 754 | + $valid_sig = ! stristr( rawurldecode( $mwpdl ), '..' ) && MainWP_System_Utility::valid_download_sig( $file, $sig_value ); | |
| 755 | 755 | |
| 756 | - if ( ! $valid_sig ) { | |
| 757 | - MainWP_Logger::instance()->debug( ' :: download :: invalid sig :: ' . base64_decode( $sig_value ) ); // phpcs:ignore -- for debug logging. | |
| 758 | - } | |
| 759 | - | |
| 760 | 756 | if ( $hasWPFileSystem && $wp_filesystem->exists( $file ) && $valid_sig ) { |
| 761 | 757 | MainWP_System_Handler::instance()->upload_file( $file ); |
| 762 | 758 | exit(); |
| 763 | 759 | } |
| 760 | + | |
| 761 | + status_header( 403 ); | |
| 762 | + header( 'Content-Type: text/plain; charset=utf-8' ); | |
| 763 | + echo 'Download link is invalid or expired.'; | |
| 764 | + exit(); | |
| 764 | 765 | } elseif ( isset( $_GET['page'] ) ) { |
| 765 | 766 | if ( MainWP_System_Utility::is_admin() && 'mainwp-setup' === $_GET['page'] ) { |
| 766 | 767 | MainWP_Setup_Wizard::get_instance(); |
| 767 | 768 | } |
| @@ -975,8 +976,9 @@ | ||
| 975 | 976 | 'installedBulkSettingsManager' => is_plugin_active( 'mainwp-bulk-settings-manager/mainwp-bulk-settings-manager.php' ) ? 1 : 0, |
| 976 | 977 | 'maximumSyncRequests' => ( get_option( 'mainwp_maximumSyncRequests' ) === false ) ? 8 : get_option( 'mainwp_maximumSyncRequests' ), |
| 977 | 978 | 'maximumInstallUpdateRequests' => ( get_option( 'mainwp_maximumInstallUpdateRequests' ) === false ) ? 3 : get_option( 'mainwp_maximumInstallUpdateRequests' ), |
| 978 | 979 | 'maximumUptimeMonitoringRequests' => (int) get_option( 'mainwp_maximum_uptime_monitoring_requests', 10 ), |
| 980 | + 'siteRemovalTimeout' => MainWP_Connect::get_site_removal_ajax_timeout_ms(), | |
| 979 | 981 | '_wpnonce' => wp_create_nonce( 'mainwp-admin-nonce' ), |
| 980 | 982 | 'quickThemeChangeNonce' => wp_create_nonce( 'mainwp_quick_theme_change' ), |
| 981 | 983 | 'demoMode' => MainWP_Demo_Handle::is_demo_mode() ? 1 : 0, |
| 982 | 984 | 'roll_ui_icon' => MainWP_Updates_Helper::get_roll_icon( '', true ), |
| @@ -1223,8 +1225,10 @@ | ||
| 1223 | 1225 | wp_enqueue_script( 'mainwp-backups', MAINWP_PLUGIN_URL . 'assets/js/mainwp-backups.js', array(), $this->current_version, true ); |
| 1224 | 1226 | wp_enqueue_script( 'mainwp-posts', MAINWP_PLUGIN_URL . 'assets/js/mainwp-posts.js', array(), $this->current_version, true ); |
| 1225 | 1227 | wp_enqueue_script( 'mainwp-users', MAINWP_PLUGIN_URL . 'assets/js/mainwp-users.js', array(), $this->current_version, true ); |
| 1226 | 1228 | wp_enqueue_script( 'mainwp-clients', MAINWP_PLUGIN_URL . 'assets/js/mainwp-clients.js', array(), $this->current_version, true ); |
| 1229 | + wp_enqueue_script( 'mainwp-knowledge', MAINWP_PLUGIN_URL . 'assets/js/mainwp-knowledge.js', array( 'jquery', 'fomantic-ui' ), $this->current_version, true ); | |
| 1230 | + wp_localize_script( 'mainwp-knowledge', 'mainwpKnowledgeStrings', MainWP_Knowledge_UI::js_strings() ); | |
| 1227 | 1231 | wp_enqueue_script( 'mainwp-extensions', MAINWP_PLUGIN_URL . 'assets/js/mainwp-extensions.js', array(), $this->current_version, true ); |
| 1228 | 1232 | wp_enqueue_script( 'moment' ); |
| 1229 | 1233 | wp_enqueue_script( 'fomantic-ui', MAINWP_PLUGIN_URL . 'assets/js/fomantic-ui/fomantic-ui.js', array( 'jquery' ), $this->current_version, false ); |
| 1230 | 1234 | |
| @@ -1235,9 +1239,10 @@ | ||
| 1235 | 1239 | |
| 1236 | 1240 | wp_enqueue_script( 'datatables-natural-sorting', MAINWP_PLUGIN_URL . 'assets/js/sorting/natural.min.js', array( 'jquery', 'datatables' ), $this->current_version, true ); |
| 1237 | 1241 | |
| 1238 | 1242 | wp_enqueue_script( 'clipboard' ); |
| 1239 | - wp_enqueue_script( 'mainwp-rest-api', MAINWP_PLUGIN_URL . 'assets/js/mainwp-rest-api.js', array(), time(), true ); | |
| 1243 | + wp_enqueue_script( 'mainwp-ai-client-setup', MAINWP_PLUGIN_URL . 'assets/js/mainwp-ai-client-setup.js', array(), $this->current_version, true ); | |
| 1244 | + wp_enqueue_script( 'mainwp-rest-api', MAINWP_PLUGIN_URL . 'assets/js/mainwp-rest-api.js', array( 'mainwp-ai-client-setup' ), time(), true ); | |
| 1240 | 1245 | |
| 1241 | 1246 | if ( isset( $_GET['page'] ) && 'ManageGroups' === $_GET['page'] ) { // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized |
| 1242 | 1247 | wp_enqueue_script( 'mainwp-groups', MAINWP_PLUGIN_URL . 'assets/js/mainwp-groups.js', array(), $this->current_version, true ); |
| 1243 | 1248 | } |
| @@ -2021,9 +2026,9 @@ | ||
| 2021 | 2026 | <div class="ui large modal" id="mainwp-response-data-modal"> |
| 2022 | 2027 | <i class="close icon"></i> |
| 2023 | 2028 | <div class="header"><?php esc_html_e( 'Child Site Response', 'mainwp' ); ?></div> |
| 2024 | 2029 | <div class="content"> |
| 2025 | - <div class="ui info message"><?php esc_html_e( 'To see the response in a more readable way, you can copy it and paste it into some HTML render tool, such as Codepen.io.', 'mainwp' ); ?> | |
| 2030 | + <div class="ui info message"><?php esc_html_e( 'This is the readable child/HTTP response from the failed request (status, headers snippet, and body when it is safe to show). Copy it for support if needed.', 'mainwp' ); ?> | |
| 2026 | 2031 | </div> |
| 2027 | 2032 | </div> |
| 2028 | 2033 | <div class="scrolling content content-response" contenteditable="true"></div> |
| 2029 | 2034 | <div class="actions"> |
| @@ -2130,8 +2135,9 @@ | ||
| 2130 | 2135 | * @uses \MainWP\Dashboard\MainWP_Install::install() |
| 2131 | 2136 | */ |
| 2132 | 2137 | public function update_install() { |
| 2133 | 2138 | MainWP_DB_Client::instance(); |
| 2139 | + MainWP_DB_Knowledge::instance(); | |
| 2134 | 2140 | MainWP_DB_Site_Actions::instance(); |
| 2135 | 2141 | MainWP_Install::instance()->install(); |
| 2136 | 2142 | $this->check_to_updates(); |
| 2137 | 2143 | } |
| @@ -2187,15 +2193,15 @@ | ||
| 2187 | 2193 | /** |
| 2188 | 2194 | * Method get_selected_sites_with_allowed_sites. |
| 2189 | 2195 | * |
| 2190 | 2196 | * @param array $selected_ids Selected sites IDs. |
| 2191 | - * @param array $current_sites Current sites IDs. | |
| 2197 | + * @param array $current_sites_ids Current sites IDs. | |
| 2192 | 2198 | * @return array Not selected but in not allowed sites in current sites ids, and selected sites ids. |
| 2193 | 2199 | */ |
| 2194 | 2200 | public static function get_selected_sites_with_allowed_sites( $selected_ids, $current_sites_ids = array() ) { |
| 2195 | 2201 | |
| 2196 | - $allowed_sites = apply_filters( 'mainwp_currentuserallowedaccesssites', 'all' ); | |
| 2197 | - if ( 'all' === $allowed_sites ) { | |
| 2202 | + $allowed_ids = MainWP_Abilities_Util::get_allowed_site_ids(); | |
| 2203 | + if ( 'all' === $allowed_ids ) { | |
| 2198 | 2204 | return $selected_ids; |
| 2199 | 2205 | } |
| 2200 | 2206 | |
| 2201 | 2207 | if ( ! is_array( $selected_ids ) ) { |
| @@ -2205,22 +2211,8 @@ | ||
| 2205 | 2211 | if ( ! is_array( $current_sites_ids ) ) { |
| 2206 | 2212 | $current_sites_ids = array(); |
| 2207 | 2213 | } |
| 2208 | 2214 | |
| 2209 | - $allowed_sites = MainWP_DB::instance()->get_websites_for_current_user(); | |
| 2210 | - if ( empty( $allowed_sites ) ) { | |
| 2211 | - return array(); | |
| 2212 | - } | |
| 2213 | - | |
| 2214 | - $allowed_ids = array_values( | |
| 2215 | - array_map( | |
| 2216 | - function ( $item ) { | |
| 2217 | - return $item->id; | |
| 2218 | - }, | |
| 2219 | - $allowed_sites | |
| 2220 | - ) | |
| 2221 | - ); | |
| 2222 | - | |
| 2223 | 2215 | $client_site_ids = array(); |
| 2224 | 2216 | foreach ( $selected_ids as $id ) { |
| 2225 | 2217 | if ( in_array( $id, $allowed_ids ) ) { |
| 2226 | 2218 | $client_site_ids[] = $id; |
| @@ -2226,8 +2218,9 @@ | ||
| 2226 | 2218 | $client_site_ids[] = $id; |
| 2227 | 2219 | } |
| 2228 | 2220 | } |
| 2229 | 2221 | |
| 2222 | + // Team Control cannot remove memberships outside the caller's site grants. | |
| 2230 | 2223 | foreach ( $current_sites_ids as $id ) { |
| 2231 | 2224 | if ( ! in_array( $id, $selected_ids ) && ! in_array( $id, $allowed_ids ) ) { // If it’s not in the allowed site IDs, the user is not permitted to change it. |
| 2232 | 2225 | $client_site_ids[] = $id; // keep this site ids. |
| 2233 | 2226 | } |