ensure( 'connection', array( 'slug' => JETPACK_PROTECT_SLUG, 'name' => JETPACK_PROTECT_NAME, 'url_info' => JETPACK_PROTECT_URI, ) ); // Sync package. $config->ensure( 'sync', array( 'jetpack_sync_modules' => array( 'Automattic\\Jetpack\\Sync\\Modules\\Options', 'Automattic\\Jetpack\\Sync\\Modules\\Callables', 'Automattic\\Jetpack\\Sync\\Modules\\Users', ), 'jetpack_sync_callable_whitelist' => array( 'main_network_site' => array( 'Automattic\\Jetpack\\Connection\\Urls', 'main_network_site_url' ), 'get_plugins' => array( 'Automattic\\Jetpack\\Sync\\Functions', 'get_plugins' ), 'get_themes' => array( 'Automattic\\Jetpack\\Sync\\Functions', 'get_themes' ), 'wp_version' => array( 'Automattic\\Jetpack\\Sync\\Functions', 'wp_version' ), ), 'jetpack_sync_options_contentless' => array(), 'jetpack_sync_options_whitelist' => array( 'active_plugins', 'stylesheet', ), ) ); // Identity crisis package. $config->ensure( 'identity_crisis' ); // Web application firewall package. $config->ensure( 'waf' ); }, 1 ); add_filter( 'jetpack_connection_user_has_license', array( $this, 'jetpack_check_user_licenses' ), 10, 3 ); add_filter( 'jetpack_get_available_standalone_modules', array( $this, 'protect_filter_available_modules' ), 10, 1 ); } /** * Initialize the plugin * * @return void */ public function init() { add_action( 'admin_bar_menu', array( $this, 'admin_bar' ), 65 ); add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_styles' ) ); REST_Controller::init(); My_Jetpack_Initializer::init(); Site_Health::init(); // Sets up JITMS. JITM::configure(); } /** * Initialize the admin page resources. */ public function admin_page_init() { $total_threats = Status::get_total_threats(); $menu_label = _x( 'Protect', 'The Jetpack Protect product name, without the Jetpack prefix', 'jetpack-protect' ); if ( $total_threats ) { $menu_label .= sprintf( ' %d', $total_threats ); } $page_suffix = Admin_Menu::add_menu( __( 'Jetpack Protect', 'jetpack-protect' ), $menu_label, 'manage_options', 'jetpack-protect', array( $this, 'plugin_settings_page' ), 5 ); add_action( 'load-' . $page_suffix, array( $this, 'enqueue_admin_scripts' ) ); } /** * Enqueues the wp-admin styles (used outside the React app) */ public function enqueue_admin_styles() { wp_enqueue_style( 'jetpack-protect-wpadmin', JETPACK_PROTECT_BASE_PLUGIN_URL . '/assets/jetpack-protect.css', array(), JETPACK_PROTECT_VERSION ); } /** * Enqueue plugin admin scripts and styles. */ public function enqueue_admin_scripts() { Assets::register_script( 'jetpack-protect', 'build/index.js', JETPACK_PROTECT_ROOT_FILE, array( 'in_footer' => true, 'textdomain' => 'jetpack-protect', ) ); Assets::enqueue_script( 'jetpack-protect' ); // Required for Analytics. wp_enqueue_script( 'jp-tracks', '//stats.wp.com/w.js', array(), gmdate( 'YW' ), true ); // Initial JS state including JP Connection data. Connection_Initial_State::render_script( 'jetpack-protect' ); wp_add_inline_script( 'jetpack-protect', $this->render_initial_state(), 'before' ); } /** * Render the initial state into a JavaScript variable. * * @return string */ public function render_initial_state() { return 'var jetpackProtectInitialState=JSON.parse(decodeURIComponent("' . rawurlencode( wp_json_encode( $this->initial_state() ) ) . '"));'; } /** * Get the initial state data for hydrating the React UI. * * @return array */ public function initial_state() { global $wp_version; // phpcs:disable WordPress.Security.NonceVerification.Recommended $refresh_status_from_wpcom = isset( $_GET['checkPlan'] ); $initial_state = array( 'apiRoot' => esc_url_raw( rest_url() ), 'apiNonce' => wp_create_nonce( 'wp_rest' ), 'registrationNonce' => wp_create_nonce( 'jetpack-registration-nonce' ), 'status' => Status::get_status( $refresh_status_from_wpcom ), 'scanHistory' => Scan_History::get_scan_history( $refresh_status_from_wpcom ), 'installedPlugins' => Plugins_Installer::get_plugins(), 'installedThemes' => Sync_Functions::get_themes(), 'wpVersion' => $wp_version, 'adminUrl' => 'admin.php?page=jetpack-protect', 'siteSuffix' => ( new Jetpack_Status() )->get_site_suffix(), 'blogID' => Connection_Manager::get_site_id( true ), 'jetpackScan' => My_Jetpack_Products::get_product( 'scan' ), 'hasRequiredPlan' => Plan::has_required_plan(), 'onboardingProgress' => Onboarding::get_current_user_progress(), 'waf' => array( 'wafSupported' => Waf_Runner::is_supported_environment(), 'currentIp' => IP_Utils::get_ip(), 'isSeen' => self::get_waf_seen_status(), 'upgradeIsSeen' => self::get_waf_upgrade_seen_status(), 'displayUpgradeBadge' => self::get_waf_upgrade_badge_display_status(), 'isEnabled' => Waf_Runner::is_enabled(), 'isToggling' => false, 'isUpdating' => false, 'config' => Waf_Runner::get_config(), 'stats' => self::get_waf_stats(), 'globalStats' => Waf_Stats::get_global_stats(), ), ); $initial_state['jetpackScan']['pricingForUi'] = Plan::get_product( 'jetpack_scan' ); return $initial_state; } /** * Main plugin settings page. */ public function plugin_settings_page() { ?>
is_connected() ) { self::activate_modules(); } } /** * Activates the waf and brute force protection modules and disables the activation option */ public static function activate_modules() { delete_option( self::JETPACK_PROTECT_ACTIVATION_OPTION ); ( new Modules() )->activate( self::JETPACK_WAF_MODULE_SLUG, false, false ); ( new Modules() )->activate( self::JETPACK_BRUTE_FORCE_PROTECTION_MODULE_SLUG, false, false ); } /** * Removes plugin from the connection manager * If it's the last plugin using the connection, the site will be disconnected. * * @access public * @static */ public static function plugin_deactivation() { // Clear Sync data. Sender::get_instance()->uninstall(); $manager = new Connection_Manager( 'jetpack-protect' ); $manager->remove_connection(); Protect_Status::delete_option(); Scan_Status::delete_option(); Scan_History::delete_option(); } /** * Create a shortcut on Admin Bar to show the total of threats found. * * @param object $wp_admin_bar The Admin Bar object. * @return void */ public function admin_bar( $wp_admin_bar ) { if ( ! current_user_can( 'manage_options' ) ) { return; } $total = Status::get_total_threats(); if ( $total > 0 ) { $args = array( 'id' => 'jetpack-protect', 'title' => '' . $total . '', 'href' => admin_url( 'admin.php?page=jetpack-protect' ), 'meta' => array( // translators: %d is the number of threats found. 'title' => sprintf( _n( '%d threat found by Jetpack Protect', '%d threats found by Jetpack Protect', $total, 'jetpack-protect' ), $total ), ), ); $wp_admin_bar->add_node( $args ); } } /** * Adds modules to the list of available modules * * @param array $modules The available modules. * @return array */ public function protect_filter_available_modules( $modules ) { return array_merge( array( self::JETPACK_WAF_MODULE_SLUG, self::JETPACK_BRUTE_FORCE_PROTECTION_MODULE_SLUG ), $modules ); } /** * Check if the user has an available license that includes Jetpack Scan. * * @param boolean $has_license Whether a license was already found. * @param object[] $licenses Unattached licenses belonging to the user. * @param string $plugin_slug Slug of the plugin that initiated the flow. * * @return boolean */ public static function jetpack_check_user_licenses( $has_license, $licenses, $plugin_slug ) { if ( $plugin_slug !== JETPACK_PROTECT_SLUG || $has_license ) { return $has_license; } $license_found = false; foreach ( $licenses as $license ) { if ( $license->attached_at || $license->revoked_at ) { continue; } if ( in_array( $license->product_id, self::JETPACK_SCAN_PRODUCT_IDS, true ) ) { $license_found = true; break; } } return $license_found; } /** * Get WAF "Seen" Status * * @return bool Whether the current user has viewed the WAF screen. */ public static function get_waf_seen_status() { return (bool) get_user_meta( get_current_user_id(), 'jetpack_protect_waf_seen', true ); } /** * Set WAF "Seen" Status * * @return bool True if seen status updated to true, false on failure. */ public static function set_waf_seen_status() { return (bool) update_user_meta( get_current_user_id(), 'jetpack_protect_waf_seen', true ); } /** * Get WAF Upgrade "Seen" Status * * @return bool Whether the current user has dismissed the upgrade popover or enabled the automatic rules feature. */ public static function get_waf_upgrade_seen_status() { return (bool) get_user_meta( get_current_user_id(), 'jetpack_protect_waf_upgrade_seen', true ); } /** * Set WAF Upgrade "Seen" Status * * @return bool True if upgrade seen status updated to true, false on failure. */ public static function set_waf_upgrade_seen_status() { self::set_waf_upgrade_badge_timestamp(); return (bool) update_user_meta( get_current_user_id(), 'jetpack_protect_waf_upgrade_seen', true ); } /** * Get WAF Upgrade Badge Timestamp * * @return integer The timestamp for the when the upgrade seen status was first set to true. */ public static function get_waf_upgrade_badge_timestamp() { return (int) get_user_meta( get_current_user_id(), 'jetpack_protect_waf_upgrade_badge_timestamp', true ); } /** * Set WAF Upgrade Badge Timestamp * * @return bool True if upgrade badge timestamp to set to the current time, false on failure. */ public static function set_waf_upgrade_badge_timestamp() { return (bool) update_user_meta( get_current_user_id(), 'jetpack_protect_waf_upgrade_badge_timestamp', time() ); } /** * Get WAF Upgrade Badge Display Status * * @return bool True if upgrade badge timestamp is set and less than 7 days ago, otherwise false. */ public static function get_waf_upgrade_badge_display_status() { $badge_timestamp_exists = metadata_exists( 'user', get_current_user_id(), 'jetpack_protect_waf_upgrade_badge_timestamp' ); if ( ! $badge_timestamp_exists ) { return true; } $badge_timestamp = self::get_waf_upgrade_badge_timestamp(); $seven_days = strtotime( '-7 days' ); if ( $badge_timestamp > $seven_days ) { return true; } return false; } /** * Get WAF stats * * @return bool|array False if WAF is not enabled, otherwise an array of stats. */ public static function get_waf_stats() { if ( ! Waf_Runner::is_enabled() ) { return false; } return array( 'ipAllowListCount' => Waf_Stats::get_ip_allow_list_count(), 'ipBlockListCount' => Waf_Stats::get_ip_block_list_count(), 'automaticRulesLastUpdated' => Waf_Stats::get_automatic_rules_last_updated(), ); } }