diff --git a/projects/packages/waf/changelog/add-protect-standalone-brute-force-access b/projects/packages/waf/changelog/add-protect-standalone-brute-force-access
new file mode 100644
index 0000000000000..987d00afe53f1
--- /dev/null
+++ b/projects/packages/waf/changelog/add-protect-standalone-brute-force-access
@@ -0,0 +1,4 @@
+Significance: minor
+Type: added
+
+Add brute force protection access for particular environments that do not support the WAF
diff --git a/projects/packages/waf/composer.json b/projects/packages/waf/composer.json
index 83383bffb0ba9..093d95799528d 100644
--- a/projects/packages/waf/composer.json
+++ b/projects/packages/waf/composer.json
@@ -60,7 +60,7 @@
"link-template": "https://github.com/Automattic/jetpack-waf/compare/v${old}...v${new}"
},
"branch-alias": {
- "dev-trunk": "0.11.x-dev"
+ "dev-trunk": "0.12.x-dev"
}
},
"config": {
diff --git a/projects/packages/waf/src/class-brute-force-protection.php b/projects/packages/waf/src/class-brute-force-protection.php
index 1437821a1624d..4c426d3437b9d 100644
--- a/projects/packages/waf/src/class-brute-force-protection.php
+++ b/projects/packages/waf/src/class-brute-force-protection.php
@@ -212,6 +212,10 @@ public static function is_enabled() {
* @return bool
*/
public static function enable() {
+ // Return true if already enabled.
+ if ( self::is_enabled() ) {
+ return true;
+ }
return ( new Modules() )->activate( 'protect', false, false );
}
@@ -221,6 +225,10 @@ public static function enable() {
* @return bool
*/
public static function disable() {
+ // Return true if already disabled.
+ if ( ! self::is_enabled() ) {
+ return true;
+ }
return ( new Modules() )->deactivate( 'protect' );
}
diff --git a/projects/packages/waf/src/class-compatibility.php b/projects/packages/waf/src/class-compatibility.php
index f20c619e6fc96..4404a556fdbeb 100644
--- a/projects/packages/waf/src/class-compatibility.php
+++ b/projects/packages/waf/src/class-compatibility.php
@@ -33,6 +33,11 @@ public static function add_compatibility_hooks() {
/**
* Run compatibility migrations.
*
+ * Note that this method should be compatible with sites where
+ * the request firewall is not active or not supported.
+ *
+ * @see Waf_Runner::is_supported_environment().
+ *
* @since 0.11.0
*
* @return void
diff --git a/projects/packages/waf/src/class-rest-controller.php b/projects/packages/waf/src/class-rest-controller.php
index 599184ff3fa43..d2ad497eb0d7a 100644
--- a/projects/packages/waf/src/class-rest-controller.php
+++ b/projects/packages/waf/src/class-rest-controller.php
@@ -145,10 +145,13 @@ public static function update_waf( $request ) {
}
}
- try {
- Waf_Runner::update_waf();
- } catch ( Waf_Exception $e ) {
- return $e->get_wp_error();
+ // Only attempt to update the WAF if the module is supported
+ if ( Waf_Runner::is_supported_environment() ) {
+ try {
+ Waf_Runner::update_waf();
+ } catch ( Waf_Exception $e ) {
+ return $e->get_wp_error();
+ }
}
return self::waf();
diff --git a/projects/packages/waf/src/class-waf-initializer.php b/projects/packages/waf/src/class-waf-initializer.php
index 823446b59823a..11891fe34910b 100644
--- a/projects/packages/waf/src/class-waf-initializer.php
+++ b/projects/packages/waf/src/class-waf-initializer.php
@@ -35,22 +35,18 @@ public static function init() {
// Ensure backwards compatibility
Waf_Compatibility::add_compatibility_hooks();
- // Register REST routes.
+ // Register REST routes
add_action( 'rest_api_init', array( new REST_Controller(), 'register_rest_routes' ) );
- // Run the WAF on supported environments
- if ( Waf_Runner::is_supported_environment() ) {
- // Update the WAF after installing or upgrading a relevant Jetpack plugin
- add_action( 'upgrader_process_complete', __CLASS__ . '::update_waf_after_plugin_upgrade', 10, 2 );
- add_action( 'admin_init', __CLASS__ . '::check_for_waf_update' );
+ // Update the WAF after installing or upgrading a relevant Jetpack plugin
+ add_action( 'upgrader_process_complete', __CLASS__ . '::update_waf_after_plugin_upgrade', 10, 2 );
- // WAF activation/deactivation hooks
- add_action( 'jetpack_activate_module_waf', __CLASS__ . '::on_waf_activation' );
- add_action( 'jetpack_deactivate_module_waf', __CLASS__ . '::on_waf_deactivation' );
+ // Check for compatibility updates
+ add_action( 'admin_init', __CLASS__ . '::check_for_updates' );
- // Run the WAF
- Waf_Runner::initialize();
- }
+ // WAF activation/deactivation hooks
+ add_action( 'jetpack_activate_module_waf', __CLASS__ . '::on_waf_activation' );
+ add_action( 'jetpack_deactivate_module_waf', __CLASS__ . '::on_waf_deactivation' );
// Brute force protection activation/deactivation hooks
add_action( 'jetpack_activate_module_protect', __CLASS__ . '::on_brute_force_protection_activation' );
@@ -58,6 +54,11 @@ public static function init() {
// Run brute force protection
Brute_Force_Protection::initialize();
+
+ // Run the WAF
+ if ( Waf_Runner::is_supported_environment() ) {
+ Waf_Runner::initialize();
+ }
}
/**
@@ -164,31 +165,37 @@ public static function update_waf_after_plugin_upgrade( $upgrader, $hook_extra )
*
* @return bool|WP_Error True if the WAF is up-to-date or was sucessfully updated, WP_Error if the update failed.
*/
- public static function check_for_waf_update() {
+ public static function check_for_updates() {
if ( get_option( self::NEEDS_UPDATE_OPTION_NAME ) ) {
- // Compatiblity patch for cases where an outdated WAF_Constants class has been
- // autoloaded by the standalone bootstrap execution at the beginning of the current request.
- if ( ! method_exists( Waf_Constants::class, 'define_mode' ) ) {
+ if ( Waf_Runner::is_supported_environment() ) {
+ // Compatiblity patch for cases where an outdated WAF_Constants class has been
+ // autoloaded by the standalone bootstrap execution at the beginning of the current request.
+ if ( ! method_exists( Waf_Constants::class, 'define_mode' ) ) {
+ try {
+ ( new Waf_Standalone_Bootstrap() )->generate();
+ } catch ( Waf_Exception $e ) {
+ return $e->get_wp_error();
+ }
+ }
+
+ Waf_Compatibility::run_compatibility_migrations();
+
+ Waf_Constants::define_mode();
+ if ( ! Waf_Runner::is_allowed_mode( JETPACK_WAF_MODE ) ) {
+ return new WP_Error( 'waf_mode_invalid', 'Invalid firewall mode.' );
+ }
+
try {
+ Waf_Rules_Manager::generate_ip_rules();
+ Waf_Rules_Manager::generate_rules();
( new Waf_Standalone_Bootstrap() )->generate();
} catch ( Waf_Exception $e ) {
return $e->get_wp_error();
}
- }
-
- Waf_Compatibility::run_compatibility_migrations();
-
- Waf_Constants::define_mode();
- if ( ! Waf_Runner::is_allowed_mode( JETPACK_WAF_MODE ) ) {
- return new WP_Error( 'waf_mode_invalid', 'Invalid firewall mode.' );
- }
-
- try {
- Waf_Rules_Manager::generate_ip_rules();
- Waf_Rules_Manager::generate_rules();
- ( new Waf_Standalone_Bootstrap() )->generate();
- } catch ( Waf_Exception $e ) {
- return $e->get_wp_error();
+ } else {
+ // If the site doesn't support the request firewall,
+ // just migrate the IP allow list used by brute force protection.
+ Waf_Compatibility::migrate_brute_force_protection_ip_allow_list();
}
}
diff --git a/projects/plugins/debug-helper/changelog/add-protect-standalone-brute-force-access b/projects/plugins/debug-helper/changelog/add-protect-standalone-brute-force-access
new file mode 100644
index 0000000000000..987d00afe53f1
--- /dev/null
+++ b/projects/plugins/debug-helper/changelog/add-protect-standalone-brute-force-access
@@ -0,0 +1,4 @@
+Significance: minor
+Type: added
+
+Add brute force protection access for particular environments that do not support the WAF
diff --git a/projects/plugins/debug-helper/modules/class-waf-helper.php b/projects/plugins/debug-helper/modules/class-waf-helper.php
index ab8f67155311f..3540ddff7685c 100644
--- a/projects/plugins/debug-helper/modules/class-waf-helper.php
+++ b/projects/plugins/debug-helper/modules/class-waf-helper.php
@@ -182,7 +182,7 @@ public function render_ui() {
Status
- Environment is supported:
+ WAF is supported:
Firewall status:
diff --git a/projects/plugins/debug-helper/plugin.php b/projects/plugins/debug-helper/plugin.php
index 54d83de771ce6..fceae1d0fb534 100644
--- a/projects/plugins/debug-helper/plugin.php
+++ b/projects/plugins/debug-helper/plugin.php
@@ -3,7 +3,7 @@
* Plugin Name: Jetpack Debug Tools
* Description: Give me a Jetpack connection, and I'll break it every way possible.
* Author: Automattic - Jetpack Crew
- * Version: 1.6.1-alpha
+ * Version: 1.7.0-alpha
* Text Domain: jetpack
*
* @package automattic/jetpack-debug-helper.
@@ -33,7 +33,7 @@
* The plugin version.
* Increase that if you do any edits to ensure refreshing the cached assets.
*/
-define( 'JETPACK_DEBUG_HELPER_VERSION', '1.6.1-alpha' );
+define( 'JETPACK_DEBUG_HELPER_VERSION', '1.7.0-alpha' );
/**
* Include file names from the modules directory here.
diff --git a/projects/plugins/jetpack/changelog/add-protect-standalone-brute-force-access b/projects/plugins/jetpack/changelog/add-protect-standalone-brute-force-access
new file mode 100644
index 0000000000000..a1c1831fa1ef7
--- /dev/null
+++ b/projects/plugins/jetpack/changelog/add-protect-standalone-brute-force-access
@@ -0,0 +1,5 @@
+Significance: patch
+Type: other
+Comment: Updated composer.lock.
+
+
diff --git a/projects/plugins/jetpack/composer.lock b/projects/plugins/jetpack/composer.lock
index abd490f4c0dba..f10f75b420997 100644
--- a/projects/plugins/jetpack/composer.lock
+++ b/projects/plugins/jetpack/composer.lock
@@ -2658,7 +2658,7 @@
"dist": {
"type": "path",
"url": "../../packages/waf",
- "reference": "278b09f381778a035f26eeb7a0905e3e87533114"
+ "reference": "233fe943efc72d8b0fcdd036a2467bb9c9710676"
},
"require": {
"automattic/jetpack-connection": "@dev",
@@ -2684,7 +2684,7 @@
"link-template": "https://github.com/Automattic/jetpack-waf/compare/v${old}...v${new}"
},
"branch-alias": {
- "dev-trunk": "0.11.x-dev"
+ "dev-trunk": "0.12.x-dev"
}
},
"autoload": {
diff --git a/projects/plugins/protect/changelog/add-protect-standalone-brute-force-access b/projects/plugins/protect/changelog/add-protect-standalone-brute-force-access
new file mode 100644
index 0000000000000..987d00afe53f1
--- /dev/null
+++ b/projects/plugins/protect/changelog/add-protect-standalone-brute-force-access
@@ -0,0 +1,4 @@
+Significance: minor
+Type: added
+
+Add brute force protection access for particular environments that do not support the WAF
diff --git a/projects/plugins/protect/changelog/add-protect-standalone-brute-force-access#2 b/projects/plugins/protect/changelog/add-protect-standalone-brute-force-access#2
new file mode 100644
index 0000000000000..9aa70e3ec1f75
--- /dev/null
+++ b/projects/plugins/protect/changelog/add-protect-standalone-brute-force-access#2
@@ -0,0 +1,5 @@
+Significance: patch
+Type: changed
+Comment: Updated composer.lock.
+
+
diff --git a/projects/plugins/protect/composer.lock b/projects/plugins/protect/composer.lock
index f6a96ee3f7850..b290643053c90 100644
--- a/projects/plugins/protect/composer.lock
+++ b/projects/plugins/protect/composer.lock
@@ -1415,7 +1415,7 @@
"dist": {
"type": "path",
"url": "../../packages/waf",
- "reference": "278b09f381778a035f26eeb7a0905e3e87533114"
+ "reference": "233fe943efc72d8b0fcdd036a2467bb9c9710676"
},
"require": {
"automattic/jetpack-connection": "@dev",
@@ -1441,7 +1441,7 @@
"link-template": "https://github.com/Automattic/jetpack-waf/compare/v${old}...v${new}"
},
"branch-alias": {
- "dev-trunk": "0.11.x-dev"
+ "dev-trunk": "0.12.x-dev"
}
},
"autoload": {
diff --git a/projects/plugins/protect/src/class-jetpack-protect.php b/projects/plugins/protect/src/class-jetpack-protect.php
index 12e6fb87e62b2..89a1aa4826eda 100644
--- a/projects/plugins/protect/src/class-jetpack-protect.php
+++ b/projects/plugins/protect/src/class-jetpack-protect.php
@@ -13,6 +13,7 @@
use Automattic\Jetpack\Assets;
use Automattic\Jetpack\Connection\Initial_State as Connection_Initial_State;
use Automattic\Jetpack\Connection\Manager as Connection_Manager;
+use Automattic\Jetpack\IP\Utils as IP_Utils;
use Automattic\Jetpack\JITMS\JITM as JITM;
use Automattic\Jetpack\Modules;
use Automattic\Jetpack\My_Jetpack\Initializer as My_Jetpack_Initializer;
@@ -218,7 +219,8 @@ public function initial_state() {
'jetpackScan' => My_Jetpack_Products::get_product( 'scan' ),
'hasRequiredPlan' => Plan::has_required_plan(),
'waf' => array(
- 'isSupported' => Waf_Runner::is_supported_environment(),
+ '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(),
diff --git a/projects/plugins/protect/src/class-rest-controller.php b/projects/plugins/protect/src/class-rest-controller.php
index 465f679d8a651..a1f3632233911 100644
--- a/projects/plugins/protect/src/class-rest-controller.php
+++ b/projects/plugins/protect/src/class-rest-controller.php
@@ -12,6 +12,7 @@
use Automattic\Jetpack\Connection\Rest_Authentication as Connection_Rest_Authentication;
use Automattic\Jetpack\Waf\Waf_Runner;
use Jetpack_Protect;
+use WP_Error;
use WP_REST_Response;
/**
diff --git a/projects/plugins/protect/src/js/components/admin-page/index.jsx b/projects/plugins/protect/src/js/components/admin-page/index.jsx
index b551c122f716d..31ec5ff5325fd 100644
--- a/projects/plugins/protect/src/js/components/admin-page/index.jsx
+++ b/projects/plugins/protect/src/js/components/admin-page/index.jsx
@@ -17,7 +17,7 @@ import useRegistrationWatcher from './use-registration-watcher';
const AdminPage = ( { children } ) => {
useRegistrationWatcher();
- const { isSupported: wafSupported, isSeen: wafSeen } = useWafData();
+ const { isSeen: wafSeen } = useWafData();
const { refreshPlan, startScanOptimistically, refreshStatus } = useDispatch( STORE_ID );
const { adminUrl } = window.jetpackProtectInitialState || {};
const { run, isRegistered, hasCheckoutStarted } = useProductCheckoutWorkflow( {
@@ -54,19 +54,17 @@ const AdminPage = ( { children } ) => {
- { wafSupported && (
-
- { __( 'Firewall', 'jetpack-protect' ) }
- { wafSeen === false && (
- { __( 'New', 'jetpack-protect' ) }
- ) }
- >
- }
- />
- ) }
+
+ { __( 'Firewall', 'jetpack-protect' ) }
+ { wafSeen === false && (
+ { __( 'New', 'jetpack-protect' ) }
+ ) }
+ >
+ }
+ />
{ children }
diff --git a/projects/plugins/protect/src/js/components/firewall-header/index.jsx b/projects/plugins/protect/src/js/components/firewall-header/index.jsx
index 317a41f9349ec..74883ee205389 100644
--- a/projects/plugins/protect/src/js/components/firewall-header/index.jsx
+++ b/projects/plugins/protect/src/js/components/firewall-header/index.jsx
@@ -95,16 +95,17 @@ const FirewallSubheading = ( {
jetpackWafIpList,
jetpackWafAutomaticRules,
bruteForceProtectionIsEnabled,
+ wafSupported,
} ) => {
- const allRules = jetpackWafAutomaticRules && jetpackWafIpList;
- const automaticRules = jetpackWafAutomaticRules && ! jetpackWafIpList;
- const manualRules = ! jetpackWafAutomaticRules && jetpackWafIpList;
- const noRules = ! jetpackWafAutomaticRules && ! jetpackWafIpList;
+ const allRules = wafSupported && jetpackWafAutomaticRules && jetpackWafIpList;
+ const automaticRules = wafSupported && jetpackWafAutomaticRules && ! jetpackWafIpList;
+ const manualRules = wafSupported && ! jetpackWafAutomaticRules && jetpackWafIpList;
+ const noRules = wafSupported && ! jetpackWafAutomaticRules && ! jetpackWafIpList;
return (
<>
- { bruteForceProtectionIsEnabled && (
+ { wafSupported && bruteForceProtectionIsEnabled && (
{
return (
@@ -166,13 +168,15 @@ const FirewallHeader = ( {
{ __( 'Active', 'jetpack-protect' ) }
- { automaticRulesEnabled
- ? __( 'Automatic firewall is on', 'jetpack-protect' )
- : __(
- 'Firewall is on',
- 'jetpack-protect',
- /* dummy arg to avoid bad minification */ 0
- ) }
+ { ! wafSupported && __( 'Brute force protection is active', 'jetpack-protect' ) }
+ { wafSupported &&
+ ( automaticRulesEnabled
+ ? __( 'Automatic firewall is on', 'jetpack-protect' )
+ : __(
+ 'Firewall is on',
+ 'jetpack-protect',
+ /* dummy arg to avoid bad minification */ 0
+ ) ) }
>
) }
@@ -188,14 +193,16 @@ const FirewallHeader = ( {
{ __( 'Inactive', 'jetpack-protect' ) }
-
- { automaticRulesAvailable
- ? __( 'Automatic firewall is off', 'jetpack-protect' )
- : __(
- 'Firewall is off',
- 'jetpack-protect',
- /* dummy arg to avoid bad minification */ 0
- ) }
+
+ { ! wafSupported && __( 'Brute force protection is disabled', 'jetpack-protect' ) }
+ { wafSupported &&
+ ( automaticRulesAvailable
+ ? __( 'Automatic firewall is off', 'jetpack-protect' )
+ : __(
+ 'Firewall is off',
+ 'jetpack-protect',
+ /* dummy arg to avoid bad minification */ 0
+ ) ) }
>
) }
@@ -235,10 +243,13 @@ const ConnectedFirewallHeader = () => {
bruteForceProtection,
},
isToggling,
+ wafSupported,
} = useWafData();
const { hasRequiredPlan } = useProtectData();
const currentStatus =
- jetpackWafAutomaticRules || jetpackWafIpList || bruteForceProtection ? 'on' : 'off';
+ ( wafSupported && ( jetpackWafAutomaticRules || jetpackWafIpList ) ) || bruteForceProtection
+ ? 'on'
+ : 'off';
return (
{
jetpackWafIpList={ jetpackWafIpList }
jetpackWafAutomaticRules={ jetpackWafAutomaticRules }
bruteForceProtectionIsEnabled={ bruteForceProtection }
+ wafSupported={ wafSupported }
/>
);
};
diff --git a/projects/plugins/protect/src/js/components/firewall-page/index.jsx b/projects/plugins/protect/src/js/components/firewall-page/index.jsx
index c320c7457e812..870adf37657af 100644
--- a/projects/plugins/protect/src/js/components/firewall-page/index.jsx
+++ b/projects/plugins/protect/src/js/components/firewall-page/index.jsx
@@ -14,8 +14,7 @@ import { createInterpolateElement } from '@wordpress/element';
import { __, sprintf, _n } from '@wordpress/i18n';
import { Icon, arrowLeft, closeSmall } from '@wordpress/icons';
import moment from 'moment';
-import { useCallback, useEffect, useState } from 'react';
-import { Navigate } from 'react-router-dom';
+import { useCallback, useEffect, useState, useMemo } from 'react';
import API from '../../api';
import { JETPACK_SCAN_SLUG, PLUGIN_SUPPORT_URL } from '../../constants';
import useAnalyticsTracks from '../../hooks/use-analytics-tracks';
@@ -27,6 +26,7 @@ import FirewallFooter from '../firewall-footer';
import ConnectedFirewallHeader from '../firewall-header';
import FormToggle from '../form-toggle';
import Notice from '../notice';
+import ScanFooter from '../scan-footer';
import Textarea from '../textarea';
import styles from './styles.module.scss';
@@ -46,20 +46,20 @@ const FirewallPage = () => {
automaticRulesAvailable,
bruteForceProtection,
},
+ currentIp,
isEnabled,
isSeen,
upgradeIsSeen,
displayUpgradeBadge,
- isSupported,
+ wafSupported,
isUpdating,
- stats,
+ stats: { ipAllowListCount, ipBlockListCount, rulesVersion, automaticRulesLastUpdated },
toggleAutomaticRules,
toggleManualRules,
toggleBruteForceProtection,
toggleWaf,
updateConfig,
} = useWafData();
- const { ipAllowListCount, ipBlockListCount, rulesVersion, automaticRulesLastUpdated } = stats;
const { hasRequiredPlan } = useProtectData();
const { run: runCheckoutWorkflow } = useProductCheckoutWorkflow( {
productSlug: JETPACK_SCAN_SLUG,
@@ -160,7 +160,7 @@ const FirewallPage = () => {
);
/**
- * Save Changes
+ * Save WAF Changes
*
* Updates the WAF settings with the current form state values.
*
@@ -252,9 +252,9 @@ const FirewallPage = () => {
] );
/**
- * Handle Automatic Rules Change
+ * Handle Brute Force Protection Change
*
- * Toggles the WAF's automatic rules option.
+ * Toggles the brute force protection module.
*
* @returns void
*/
@@ -345,6 +345,32 @@ const FirewallPage = () => {
API.wafUpgradeSeen();
}, [ setWafUpgradeIsSeen ] );
+ /**
+ * Checks if the current IP address is allow listed.
+ *
+ * @returns {boolean} - Indicates whether the current IP address is allow listed.
+ */
+ const isCurrentIpAllowed = useMemo( () => {
+ return formState.jetpack_waf_ip_allow_list.includes( currentIp );
+ }, [ formState.jetpack_waf_ip_allow_list, currentIp ] );
+
+ /**
+ * Adds the current IP address to the IP allow list.
+ *
+ * @returns {void}
+ */
+ const addCurrentIpToAllowList = useCallback( () => {
+ const updatedList =
+ formState.jetpack_waf_ip_allow_list.length > 0
+ ? `${ formState.jetpack_waf_ip_allow_list }\n${ currentIp }`
+ : currentIp;
+
+ setFormState( prevState => ( {
+ ...prevState,
+ jetpack_waf_ip_allow_list: updatedList,
+ } ) );
+ }, [ formState.jetpack_waf_ip_allow_list, currentIp ] );
+
/**
* Sync formState with application state WAF config
*/
@@ -413,10 +439,10 @@ const FirewallPage = () => {
);
/**
- * Main Settings
+ * Automatic Firewall Rules Settings
*/
- const mainSettings = (
-
+ const automaticRulesSettings = (
+ <>
{
/>
) }
+ >
+ );
+
+ const bruteForceAllowListSettings = (
+ <>
+
+
+ >
+ );
+
+ const bruteForceProtectionSettings = (
+ <>
-
-
-
-
-
-
- { __( 'Enable manual block and allow lists', 'jetpack-protect' ) }
-
-
- { __(
- 'Manually block or allow traffic from specific IP addresses.',
- 'jetpack-protect'
- ) }
-
- { jetpackWafIpList && (
-
-
- { ipAllowListCount === 0 && ipBlockListCount === 0 && (
-
- { __( 'No manual rules are being applied.', 'jetpack-protect' ) }
-
- ) }
- { ipBlockListCount > 0 && (
-
- { sprintf(
- // translators: placeholder is a number of blocked IP addresses i.e. "5 IPs are being blocked".
- _n(
- '%s IP is being blocked. ',
- '%s IPs are being blocked. ',
- ipBlockListCount,
- 'jetpack-protect'
- ),
- ipBlockListCount === 1 ? 'One' : ipBlockListCount
- ) }
-
- ) }
- { ipAllowListCount > 0 && (
-
- { sprintf(
- // translators: placeholder is a number of allowed IP addresses i.e. "5 IPs are being allowed".
- _n(
- '%s IP is being allowed.',
- '%s IPs are being allowed.',
- ipAllowListCount,
- 'jetpack-protect'
- ),
- ipAllowListCount === 1 ? 'One' : ipAllowListCount
- ) }
+ { ! wafSupported && formState.brute_force_protection && bruteForceAllowListSettings }
+ >
+ );
+
+ /**
+ * Main Settings
+ */
+ const mainSettings = (
+
+ { wafSupported && automaticRulesSettings }
+ { bruteForceProtectionSettings }
+ { wafSupported && (
+
+
+
+
+
+
+ { __( 'Enable manual block and allow lists', 'jetpack-protect' ) }
+
+
+ { __(
+ 'Manually block or allow traffic from specific IP addresses.',
+ 'jetpack-protect'
+ ) }
+
+ { jetpackWafIpList && (
+
+
+ { ipAllowListCount === 0 && ipBlockListCount === 0 && (
+
+ { __( 'No manual rules are being applied.', 'jetpack-protect' ) }
+
+ ) }
+ { ipBlockListCount > 0 && (
+
+ { sprintf(
+ // translators: placeholder is a number of blocked IP addresses i.e. "5 IPs are being blocked".
+ _n(
+ '%s IP is being blocked. ',
+ '%s IPs are being blocked. ',
+ ipBlockListCount,
+ 'jetpack-protect'
+ ),
+ ipBlockListCount === 1 ? 'One' : ipBlockListCount
+ ) }
+
+ ) }
+ { ipAllowListCount > 0 && (
+
+ { sprintf(
+ // translators: placeholder is a number of allowed IP addresses i.e. "5 IPs are being allowed".
+ _n(
+ '%s IP is being allowed.',
+ '%s IPs are being allowed.',
+ ipAllowListCount,
+ 'jetpack-protect'
+ ),
+ ipAllowListCount === 1 ? 'One' : ipAllowListCount
+ ) }
+
+ ) }
+
+
-
-
- ) }
+ ) }
+
-
+ ) }
);
@@ -681,21 +776,47 @@ const FirewallPage = () => {
'jetpack-protect'
) }
-
-
-
+ { wafSupported && (
+
+
+
+ ) }
+ }
placeholder={ __( 'Example:', 'jetpack-protect' ) + '\n12.12.12.1\n12.12.12.2' }
rows={ 3 }
value={ formState.jetpack_waf_ip_allow_list }
@@ -709,25 +830,18 @@ const FirewallPage = () => {
);
- /**
- * Do not allow this page to be accessed on unsupported platforms.
- */
- if ( ! isSupported ) {
- return
;
- }
-
/**
* Render
*/
return (
{ notice.message && }
-
+ { }
- { ! isEnabled && { moduleDisabledNotice } }
+ { wafSupported && ! isEnabled && { moduleDisabledNotice } }
{ ! showManualRules ? mainSettings : manualRulesSettings }
-
+ { wafSupported ? : }
);
};
diff --git a/projects/plugins/protect/src/js/components/firewall-page/styles.module.scss b/projects/plugins/protect/src/js/components/firewall-page/styles.module.scss
index d6d445909db51..30dae7cd12362 100644
--- a/projects/plugins/protect/src/js/components/firewall-page/styles.module.scss
+++ b/projects/plugins/protect/src/js/components/firewall-page/styles.module.scss
@@ -94,6 +94,11 @@
margin-bottom: calc( var( --spacing-base ) * 4 ); // 32px
}
+.brute-force-rules-section {
+ margin-top: calc( var( --spacing-base ) * 6 ); // 32px
+ margin-bottom: calc( var( --spacing-base ) * 2 ); // 32px
+}
+
.go-back-button {
margin: calc( var( --spacing-base ) * -1 ) calc( var( --spacing-base ) * -2 ); // -8px | -16px
}
@@ -133,3 +138,30 @@
justify-content: flex-end;
}
}
+
+.status {
+ color: var( --jp-gray-50 );
+
+ &:before {
+ content: "";
+ display: inline-block;
+ border-radius: 50%;
+ height: 8px;
+ width: 8px;
+ margin-right: var(--spacing-base); // 8px
+ background: var( --jp-gray-50 );
+ }
+
+ &.active {
+ color: var( --jp-green-40 );
+
+ &:before {
+ background: var( --jp-green-40 );
+ }
+ }
+}
+
+.current-ip-text {
+ margin-top: calc( var( --spacing-base ) * 2 );
+ margin-bottom: calc( var( --spacing-base ) * 3);
+}
diff --git a/projects/plugins/protect/src/js/components/scan-footer/styles.module.scss b/projects/plugins/protect/src/js/components/scan-footer/styles.module.scss
index cdb0426be8c9c..d4249719742ca 100644
--- a/projects/plugins/protect/src/js/components/scan-footer/styles.module.scss
+++ b/projects/plugins/protect/src/js/components/scan-footer/styles.module.scss
@@ -1,3 +1,4 @@
.product-section, .info-section {
margin-top: calc( var( --spacing-base ) * 7 ); // 56px
-}
\ No newline at end of file
+ margin-bottom: calc( var( --spacing-base ) * 7 ); // 56px
+}
diff --git a/projects/plugins/protect/src/js/components/textarea/index.jsx b/projects/plugins/protect/src/js/components/textarea/index.jsx
index 55850e1fe3efb..224e482f552ca 100644
--- a/projects/plugins/protect/src/js/components/textarea/index.jsx
+++ b/projects/plugins/protect/src/js/components/textarea/index.jsx
@@ -4,6 +4,7 @@ const Textarea = ( {
disabled = false,
id,
label = '',
+ description = '',
placeholder = '',
rows = 3,
value = '',
@@ -16,6 +17,7 @@ const Textarea = ( {
{ label }
) }
+ { Boolean( description ) && description }