Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Protect: Separate scanner and history views via React Router and UI adjustments #38325

Merged
Merged
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: added

Add Scan History model.
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
/**
* Model class for Protect history report data.
*
* @package automattic/jetpack-protect-plugin
* @package automattic/jetpack-protect-models
*/

namespace Automattic\Jetpack\Protect;
namespace Automattic\Jetpack\Protect_Models;

/**
* Model class for the Protect history report data.
Expand All @@ -18,13 +18,6 @@ class History_Model {
*/
public $last_checked;

/**
* The filter to apply to the history.
*
* @var array
*/
public $filter = array( 'ignored', 'fixed' );

/**
* The number of threats.
*
Expand Down
7 changes: 7 additions & 0 deletions projects/packages/protect-models/src/class-threat-model.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@ class Threat_Model {
*/
public $fixed_in;

/**
* The date the threat is fixed on.
*
* @var null|string
*/
public $fixed_on;

/**
* The severity of the threat between 1-5.
*
Expand Down
1 change: 0 additions & 1 deletion projects/plugins/protect/src/class-jetpack-protect.php
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,6 @@ public function initial_state() {
'apiNonce' => wp_create_nonce( 'wp_rest' ),
'registrationNonce' => wp_create_nonce( 'jetpack-registration-nonce' ),
'status' => Status::get_status( $refresh_status_from_wpcom ),
'viewingScanHistory' => false,
'scanHistory' => Scan_History::get_scan_history( $refresh_status_from_wpcom ),
'installedPlugins' => Plugins_Installer::get_plugins(),
'installedThemes' => Sync_Functions::get_themes(),
Expand Down
20 changes: 3 additions & 17 deletions projects/plugins/protect/src/class-rest-controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -203,25 +203,13 @@ public static function register_rest_endpoints() {
'jetpack-protect/v1',
'scan-history',
array(
'methods' => \WP_REST_Server::EDITABLE,
'methods' => \WP_REST_Server::READABLE,
'callback' => __CLASS__ . '::api_get_scan_history',
'permission_callback' => function () {
return current_user_can( 'manage_options' );
},
)
);

register_rest_route(
'jetpack-protect/v1',
'clear-scan-history-cache',
array(
'methods' => \WP_REST_Server::EDITABLE,
'callback' => __CLASS__ . '::api_clear_scan_history_cache',
'permission_callback' => function () {
return current_user_can( 'manage_options' );
},
)
);
}

/**
Expand Down Expand Up @@ -437,12 +425,10 @@ public static function api_complete_onboarding_steps( $request ) {
/**
* Return Scan History for the API endpoint
*
* @param WP_REST_Request $request The request object.
*
* @return WP_REST_Response
*/
public static function api_get_scan_history( $request ) {
$scan_history = Scan_History::get_scan_history( false, $request['filter'] );
public static function api_get_scan_history() {
$scan_history = Scan_History::get_scan_history( false );
return rest_ensure_response( $scan_history, 200 );
}

Expand Down
20 changes: 6 additions & 14 deletions projects/plugins/protect/src/class-scan-history.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
use Automattic\Jetpack\Connection\Client;
use Automattic\Jetpack\Connection\Manager as Connection_Manager;
use Automattic\Jetpack\Protect_Models\Extension_Model;
use Automattic\Jetpack\Protect_Models\History_Model;
use Automattic\Jetpack\Protect_Models\Threat_Model;
use Automattic\Jetpack\Protect_Status\Plan;
use Jetpack_Options;
use WP_Error;
Expand Down Expand Up @@ -113,11 +115,10 @@ public static function delete_option() {
/**
* Gets the current history of the Jetpack Protect checks
*
* @param bool $refresh_from_wpcom Refresh the local plan and history cache from wpcom.
* @param array $filter The filter to apply to the data.
* @param bool $refresh_from_wpcom Refresh the local plan and history cache from wpcom.
* @return History_Model|bool
*/
public static function get_scan_history( $refresh_from_wpcom = false, $filter = null ) {
public static function get_scan_history( $refresh_from_wpcom = false ) {
$has_required_plan = Plan::has_required_plan();
if ( ! $has_required_plan ) {
return false;
Expand All @@ -142,7 +143,7 @@ public static function get_scan_history( $refresh_from_wpcom = false, $filter =
)
);
} else {
$history = self::normalize_api_data( $history, $filter );
$history = self::normalize_api_data( $history );
}

self::$history = $history;
Expand Down Expand Up @@ -204,31 +205,22 @@ public static function fetch_from_api() {
* Formats the payload from the Scan API into an instance of History_Model.
*
* @param object $scan_data The data returned by the scan API.
* @param array $filter The filter to apply to the data.
* @return History_Model
*/
private static function normalize_api_data( $scan_data, $filter ) {
private static function normalize_api_data( $scan_data ) {
$history = new History_Model();
$history->num_threats = 0;
$history->num_core_threats = 0;
$history->num_plugins_threats = 0;
$history->num_themes_threats = 0;

if ( $filter ) {
$history->filter = $filter;
}

$history->last_checked = $scan_data->last_checked;

if ( empty( $scan_data->threats ) || ! is_array( $scan_data->threats ) ) {
return $history;
}

foreach ( $scan_data->threats as $threat ) {
if ( ! in_array( $threat->status, $history->filter, true ) ) {
continue;
}

if ( isset( $threat->extension->type ) ) {
if ( 'plugin' === $threat->extension->type ) {
self::handle_extension_threats( $threat, $history, 'plugin' );
Expand Down
5 changes: 2 additions & 3 deletions projects/plugins/protect/src/js/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,10 @@ const API = {
data: { step_ids: stepIds },
} ),

fetchScanHistory: $filter =>
fetchScanHistory: () =>
apiFetch( {
path: 'jetpack-protect/v1/scan-history',
method: 'POST',
data: { filter: $filter },
method: 'GET',
} ),
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ const AdminPage = ( { children } ) => {

const { isSeen: wafSeen } = useWafData();
const notice = useSelect( select => select( STORE_ID ).getNotice() );
const { refreshPlan, startScanOptimistically, refreshStatus } = useDispatch( STORE_ID );
const { refreshPlan, startScanOptimistically, refreshStatus, refreshScanHistory } =
useDispatch( STORE_ID );
const { adminUrl } = window.jetpackProtectInitialState || {};
const { run, isRegistered, hasCheckoutStarted } = useProductCheckoutWorkflow( {
productSlug: JETPACK_SCAN_SLUG,
Expand All @@ -39,9 +40,10 @@ const AdminPage = ( { children } ) => {
setTimeout( () => {
refreshPlan();
refreshStatus( true );
refreshScanHistory();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason why we shouldn't treat this like refreshStatus with a hard refresh?

}, 5000 );
}
}, [ refreshPlan, refreshStatus, startScanOptimistically ] );
}, [ refreshPlan, refreshStatus, refreshScanHistory, startScanOptimistically ] );

/*
* Show interstital page when
Expand All @@ -57,7 +59,7 @@ const AdminPage = ( { children } ) => {
{ notice.message && <Notice floating={ true } dismissable={ true } { ...notice } /> }
<Container horizontalSpacing={ 0 }>
<Tabs className={ styles.navigation }>
<Tab link="/" label={ __( 'Scan', 'jetpack-protect' ) } />
<Tab link="/scan" label={ __( 'Scan', 'jetpack-protect' ) } />
<Tab
link="/firewall"
label={
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ import { STORE_ID } from '../../state/store';

const useRegistrationWatcher = () => {
const { isRegistered } = useConnection();
const { refreshStatus } = useDispatch( STORE_ID );
const { refreshStatus, refreshScanHistory } = useDispatch( STORE_ID );
const status = useSelect( select => select( STORE_ID ).getStatus() );

useEffect( () => {
if ( isRegistered && ! status.status ) {
refreshStatus();
refreshScanHistory();
}
// We don't want to run the effect if status changes. Only on changes on isRegistered.
// eslint-disable-next-line react-hooks/exhaustive-deps
Expand Down
24 changes: 24 additions & 0 deletions projects/plugins/protect/src/js/components/button-group/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Button } from '@automattic/jetpack-components';
import { ButtonGroup as WordPressButtonGroup } from '@wordpress/components';
import React from 'react';
import styles from './styles.module.scss';

/**
* Button Group
*
* @param {object} props - Component props.
* @param { React.ReactNode } props.children - Component children.
*
* @returns { React.ReactNode } The Button Group component.
*/
function ButtonGroup( { children, ...props } ) {
return (
<WordPressButtonGroup className={ styles[ 'button-group' ] } { ...props }>
{ children }
</WordPressButtonGroup>
);
}

ButtonGroup.Button = props => <Button { ...props } />;

export default ButtonGroup;
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/* eslint-disable react/react-in-jsx-scope */
import { Button } from '@automattic/jetpack-components';
import React from 'react';
import ButtonGroup from '../index.jsx';

export default {
title: 'Plugins/Protect/Button Group',
component: ButtonGroup,
argTypes: {},
};

const Template = args => (
<ButtonGroup { ...args }>
<Button>Button 1</Button>
<Button>Button 2</Button>
</ButtonGroup>
);
export const Default = Template.bind( {} );
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
.button-group {
:global .components-button {
position: relative;
box-shadow: inset 0 0 0 1.5px var( --jp-gray );

&:first-child {
border-radius: var(--jp-border-radius) 0 0 var(--jp-border-radius);
}

&:last-child {
border-radius: 0 var(--jp-border-radius) var(--jp-border-radius) 0;
}

&:hover {
z-index: 1;
}

+ .components-button {
margin-left: -1.5px;
}
}
}
Loading
Loading