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

ThreatsDataViews: ThreatModal integration #40202

Open
wants to merge 84 commits into
base: trunk
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
84 commits
Select commit Hold shift + click to select a range
b919756
Add ThreatDetailsModal component and stories
dkmyta Nov 14, 2024
15587ca
changelog
dkmyta Nov 14, 2024
2bebb0d
Fix type error
dkmyta Nov 14, 2024
dddfdaf
Fix child component overflow-x styling
dkmyta Nov 14, 2024
172fbb0
Update scan package changelog
dkmyta Nov 14, 2024
d39a616
Add util for fixerState and separate subcomponents
dkmyta Nov 14, 2024
e1c5bf4
Add ThreatDetailsModal to ThreatsDataViews
dkmyta Nov 14, 2024
9f0892e
Add user connection gate
dkmyta Nov 15, 2024
d955bb1
Add credentials gate
dkmyta Nov 15, 2024
32a7559
Fix stories
dkmyta Nov 15, 2024
d1d546e
Fix stories
dkmyta Nov 15, 2024
9d86cb5
Merge branch 'add/components/threat-details-modal-credentials-gate' i…
dkmyta Nov 15, 2024
69b0756
Fix credentials type
dkmyta Nov 15, 2024
2f59aa8
Update content flow
dkmyta Nov 15, 2024
30ab005
Improve organization
dkmyta Nov 15, 2024
05ac09a
Separation and reorg
dkmyta Nov 15, 2024
1f25735
Improve
dkmyta Nov 15, 2024
8755dc7
Remove redundant code
dkmyta Nov 15, 2024
e7ff731
Adjust modal content
dkmyta Nov 15, 2024
c8bcd82
Merge branch 'update/components/threat-details-modal-flow' into add/c…
dkmyta Nov 15, 2024
0aef3cd
Fix implementation and stories
dkmyta Nov 15, 2024
00511f6
Update flag
dkmyta Nov 18, 2024
6083c25
Fix display logic
dkmyta Nov 18, 2024
8c09917
Add showThreatDetails action to threat title
dkmyta Nov 18, 2024
c21ba42
Move context provided a component level up
dkmyta Nov 18, 2024
e6ca520
Reorg and fix stories
dkmyta Nov 18, 2024
924768a
changelog
dkmyta Nov 18, 2024
abde93a
Remove unintended changes
dkmyta Nov 18, 2024
fddb7f9
Generalize component name
dkmyta Nov 18, 2024
d3aaff7
Updates after renaming
dkmyta Nov 18, 2024
3851638
Ensure close button exists for vulns modal
dkmyta Nov 18, 2024
ed6fd3c
Merge branch 'trunk' into add/components/threat-details-modal
dkmyta Nov 18, 2024
cc3c1a2
Rebase
dkmyta Nov 18, 2024
5f0f5f1
Rebase
dkmyta Nov 18, 2024
1dbbddf
Rebase
dkmyta Nov 18, 2024
9aecbbb
Rebase, fix conflicts
dkmyta Nov 19, 2024
0c7099e
changelog
dkmyta Nov 19, 2024
6708378
Updates/fixes
dkmyta Nov 19, 2024
a8eed1e
Rebase, fix conflicts
dkmyta Nov 19, 2024
8b11f5f
Add utility for retrieving detailed action
dkmyta Nov 19, 2024
4e50a26
changelog
dkmyta Nov 19, 2024
4709a1c
Add detailed action
dkmyta Nov 19, 2024
799aa0b
changelog
dkmyta Nov 19, 2024
6c19fcd
Add actionToConfirm flag for rendering conditional content based on a…
dkmyta Nov 19, 2024
a134a4e
Update approach to single view
dkmyta Nov 20, 2024
c084a5f
Move notices to ThreatActions
dkmyta Nov 20, 2024
5533413
Rebase
dkmyta Nov 20, 2024
03eb1ba
Add fixer notices
dkmyta Nov 20, 2024
b33d1d1
Add fixer notices
dkmyta Nov 21, 2024
3541623
Fix styling
dkmyta Nov 21, 2024
0032d03
Additional improvements
dkmyta Nov 21, 2024
d028679
Fix gap
dkmyta Nov 21, 2024
daf8c58
Rebase
dkmyta Nov 21, 2024
a6d4c3a
Fix conflicts
dkmyta Nov 21, 2024
b7d60ff
Fix styles
dkmyta Nov 21, 2024
a67f639
Add ignore confirmation details
dkmyta Nov 21, 2024
962a992
Add modal fixer confirmation context
dkmyta Nov 21, 2024
5860eca
Reorg
dkmyta Nov 21, 2024
84bf4fd
Remove actionToConfirm flag, to be readded in integration
dkmyta Nov 21, 2024
344696a
Early return on ThreatActions for fixed threats
dkmyta Nov 21, 2024
baeaacf
Rebase
dkmyta Nov 21, 2024
242ca8f
Make threat status check optional
dkmyta Nov 21, 2024
6807ee6
Merge branch 'update/components/threat-details-modal-flow' into add/c…
dkmyta Nov 21, 2024
c01432f
Fix stories
dkmyta Nov 21, 2024
9151f92
Merge branch 'trunk' into update/components/threat-details-modal-flow
dkmyta Nov 21, 2024
f02fa61
Merge branch 'update/components/threat-details-modal-flow' into add/c…
dkmyta Nov 21, 2024
9093f0a
Fix tests
dkmyta Nov 21, 2024
a02bff6
Remove jest
dkmyta Nov 21, 2024
220d28c
Use custom button for threat details toggle (#40298)
nateweller Nov 22, 2024
896f7e0
Use Button and override internal styles
dkmyta Nov 22, 2024
41e563f
Fix classes
dkmyta Nov 22, 2024
94ed99a
Move fixerState comp to ThreatFixConfirmation
dkmyta Nov 22, 2024
33268ee
Rely heavily on context provider
dkmyta Nov 22, 2024
a68be5e
Rebase, fix stories
dkmyta Nov 22, 2024
1e2333e
Fix styles
dkmyta Nov 25, 2024
6815e0e
Merge branch 'update/components/threat-details-modal-flow' into add/c…
dkmyta Nov 25, 2024
538694f
Add support link
dkmyta Nov 25, 2024
e390d43
Fix threat action buttons in mobile
dkmyta Nov 25, 2024
572cc10
Merge trunk, fix conflicts
dkmyta Nov 25, 2024
b085648
changelog
dkmyta Nov 25, 2024
4daadc6
Fix focus styling issues
dkmyta Nov 25, 2024
1716a45
Add slight padding to overflow issues
dkmyta Nov 25, 2024
aa0f8e5
Add global override, over awkward title offset
dkmyta Nov 25, 2024
fbd7091
Remove unneeded styles while global override is in place
dkmyta Nov 25, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: added

Integrates ThreatModal in ThreatsDataViews
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import { Button } from '@automattic/jetpack-components';
import { CONTACT_SUPPORT_URL } from '@automattic/jetpack-scan';
import { createInterpolateElement } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { useMemo } from 'react';
import styles from './styles.module.scss';
Expand All @@ -19,14 +22,28 @@ const FixerStateNotice = ( {
}: {
fixerState: { inProgress: boolean; error: boolean; stale: boolean };
} ) => {
const getInterpolatedContent = (): JSX.Element => {
return createInterpolateElement(
__( 'Please try again or <supportLink>contact support</supportLink>.', 'jetpack' ),
{
supportLink: <Button variant="link" isExternalLink={ true } href={ CONTACT_SUPPORT_URL } />,
}
);
};

const { status, title, content } = useMemo( () => {
if ( fixerState.error ) {
return {
status: 'error' as const,
title: __( 'An error occurred auto-fixing this threat', 'jetpack' ),
content: __(
'Jetpack encountered a filesystem error while attempting to auto-fix this threat. Please try again later or contact support.',
'jetpack'
content: (
<>
{ __(
'Jetpack encountered a filesystem error while attempting to auto-fix this threat.',
'jetpack'
) }{ ' ' }
{ getInterpolatedContent() }
</>
),
};
}
Expand All @@ -35,9 +52,14 @@ const FixerStateNotice = ( {
return {
status: 'error' as const,
title: __( 'The auto-fixer is taking longer than expected', 'jetpack' ),
content: __(
'Jetpack has been attempting to auto-fix this threat for too long, and something may have gone wrong. Please try again later or contact support.',
'jetpack'
content: (
<>
{ __(
'Jetpack has been attempting to auto-fix this threat for too long, and something may have gone wrong.',
'jetpack'
) }{ ' ' }
{ getInterpolatedContent() }
</>
),
};
}
Expand All @@ -55,7 +77,7 @@ const FixerStateNotice = ( {

return title ? (
<div className={ styles[ 'fixer-notice' ] }>
<ThreatNotice status={ status } title={ title } content={ content } />
<ThreatNotice status={ status } title={ title } content={ content } showActions={ false } />
</div>
) : null;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import ThreatFixConfirmation from './threat-fix-confirmation';
interface ThreatModalContextType {
closeModal: () => void;
threat: Threat;
actionToConfirm: string | null;
handleUpgradeClick?: () => void;
userConnectionNeeded: boolean;
handleConnectUser: () => void;
Expand Down Expand Up @@ -38,6 +39,7 @@ export const ThreatModalContext = createContext< ThreatModalContextType | null >
* @param {Function} props.handleFixThreatClick - The handleFixThreatClick function.
* @param {Function} props.handleIgnoreThreatClick - The handleIgnoreThreatClick function.
* @param {Function} props.handleUnignoreThreatClick - The handleUnignoreThreatClick function.
* @param {string} props.actionToConfirm - The action to confirm.
*
* @return {JSX.Element} The threat modal.
*/
Expand All @@ -54,6 +56,7 @@ export default function ThreatModal( {
handleFixThreatClick,
handleIgnoreThreatClick,
handleUnignoreThreatClick,
actionToConfirm,
...modalProps
}: {
threat: Threat;
Expand All @@ -68,6 +71,7 @@ export default function ThreatModal( {
handleFixThreatClick?: ( threats: Threat[] ) => void;
handleIgnoreThreatClick?: ( threats: Threat[] ) => void;
handleUnignoreThreatClick?: ( threats: Threat[] ) => void;
actionToConfirm: string | null;
} & React.ComponentProps< typeof Modal > ): JSX.Element {
const userConnectionNeeded = ! isUserConnected || ! hasConnectedOwner;
const siteCredentialsNeeded = ! credentials || credentials.length === 0;
Expand All @@ -88,6 +92,7 @@ export default function ThreatModal( {
value={ {
closeModal: modalProps.onRequestClose,
threat,
actionToConfirm,
handleUpgradeClick,
userConnectionNeeded,
handleConnectUser,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@ const Base = args => {
const [ isOpen, setIsOpen ] = useState( false );
const onClick = useCallback( () => setIsOpen( true ), [] );
const onRequestClose = useCallback( () => setIsOpen( false ), [] );

return (
<div>
<Button onClick={ onClick }>Open Threat Modal</Button>
{ isOpen ? <ThreatModal { ...args } onRequestClose={ onRequestClose } /> : null }
{ isOpen ? (
<ThreatModal { ...args } onRequestClose={ onRequestClose } actionToConfirm={ 'all' } />
) : null }
</div>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,19 @@
display: flex;
flex-direction: column;
gap: calc( var( --spacing-base ) * 2 ); // 16px
}

.section .section__toggle {
text-decoration: none;

&:hover {
text-decoration: underline;
}

&__content {
display: flex;
gap: calc( var( --spacing-base ) / 2 ); // 4px
align-items: center;
.section__toggle {
text-decoration: none;

&:hover {
text-decoration: underline;
}

&__content {
display: flex;
gap: calc( var( --spacing-base ) / 2 ); // 4px
align-items: center;
}
}
}

Expand All @@ -43,6 +43,7 @@
.threat-actions {
display: flex;
justify-content: flex-end;
flex-wrap: wrap;
gap: calc( var( --spacing-base ) * 2 ); // 16px;
}
}
Expand All @@ -55,10 +56,6 @@
&__title {
display: flex;
gap: calc( var( --spacing-base ) / 2 ); // 4px

p {
font-weight: bold;
}
}

&__actions {
Expand All @@ -77,5 +74,4 @@ svg.spinner {
width: 20px;
margin-left: calc( var( --spacing-base ) / 2 ); // 4px;
margin-right: 6px;

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const ThreatActions = (): JSX.Element => {
const {
closeModal,
threat,
actionToConfirm,
handleFixThreatClick,
handleIgnoreThreatClick,
handleUnignoreThreatClick,
Expand Down Expand Up @@ -64,15 +65,17 @@ const ThreatActions = (): JSX.Element => {
) }
{ threat.status === 'current' && (
<>
<Button
isDestructive={ true }
variant="secondary"
onClick={ onIgnoreClick }
disabled={ disabled || ( fixerState.inProgress && ! fixerState.stale ) }
>
{ __( 'Ignore threat', 'jetpack' ) }
</Button>
{ threat.fixable && (
{ [ 'all', 'ignore' ].includes( actionToConfirm ) && (
<Button
isDestructive={ true }
variant="secondary"
onClick={ onIgnoreClick }
disabled={ disabled || ( fixerState.inProgress && ! fixerState.stale ) }
>
{ __( 'Ignore threat', 'jetpack' ) }
</Button>
) }
{ threat.fixable && [ 'all', 'fix' ].includes( actionToConfirm ) && (
<Button
isPrimary
disabled={ disabled || ( fixerState.inProgress && ! fixerState.stale ) }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { __ } from '@wordpress/i18n';
import { useContext } from 'react';
import ContextualUpgradeTrigger from '../contextual-upgrade-trigger';
import ThreatActions from './threat-actions';
import ThreatFixDetails from './threat-fix-details';
import ThreatIgnoreDetails from './threat-ignore-details';
import ThreatNotice from './threat-notice';
import ThreatSummary from './threat-summary';
import ThreatTechnicalDetails from './threat-technical-details';
Expand All @@ -13,12 +15,15 @@ import { ThreatModalContext } from '.';
* @return {JSX.Element} The rendered fix confirmation.
*/
const ThreatFixConfirmation = () => {
const { userConnectionNeeded, siteCredentialsNeeded } = useContext( ThreatModalContext );
const { actionToConfirm, userConnectionNeeded, siteCredentialsNeeded, handleUpgradeClick } =
useContext( ThreatModalContext );
return (
<>
<ThreatSummary />
<ThreatTechnicalDetails />
<ThreatFixDetails />
{ [ 'all', 'fix' ].includes( actionToConfirm ) && <ThreatFixDetails /> }
{ /* TODO: Necessary to show ignore confirmation in all view? */ }
{ [ 'all', 'ignore' ].includes( actionToConfirm ) && <ThreatIgnoreDetails /> }
{ siteCredentialsNeeded && userConnectionNeeded && (
<ThreatNotice
title={ 'Additional connections needed' }
Expand Down Expand Up @@ -46,6 +51,13 @@ const ThreatFixConfirmation = () => {
) }
/>
) }
{ handleUpgradeClick && (
<ContextualUpgradeTrigger
description={ __( 'Looking for advanced scan results and one-click fixes?', 'jetpack' ) }
cta={ __( 'Upgrade Jetpack now', 'jetpack' ) }
onClick={ handleUpgradeClick }
/>
) }
<ThreatActions />
</>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { getFixerDescription } from '@automattic/jetpack-scan';
import { __, sprintf } from '@wordpress/i18n';
import React, { useMemo, useContext } from 'react';
import ContextualUpgradeTrigger from '../contextual-upgrade-trigger';
import Text from '../text';
import styles from './styles.module.scss';
import { ThreatModalContext } from '.';
Expand All @@ -12,7 +11,7 @@ import { ThreatModalContext } from '.';
* @return {JSX.Element | null} The rendered fix details or null if no fixable details are available.
*/
const ThreatFixDetails = (): JSX.Element => {
const { threat, handleUpgradeClick } = useContext( ThreatModalContext );
const { threat } = useContext( ThreatModalContext );

const title = useMemo( () => {
if ( threat.status === 'fixed' ) {
Expand Down Expand Up @@ -48,13 +47,6 @@ const ThreatFixDetails = (): JSX.Element => {
<div className={ styles.section }>
<Text variant="title-small">{ title }</Text>
<Text>{ fix }</Text>
{ handleUpgradeClick && (
<ContextualUpgradeTrigger
description={ __( 'Looking for advanced scan results and one-click fixes?', 'jetpack' ) }
cta={ __( 'Upgrade Jetpack now', 'jetpack' ) }
onClick={ handleUpgradeClick }
/>
) }
</div>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { Text, Button, getRedirectUrl } from '@automattic/jetpack-components';
import { createInterpolateElement } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { useContext } from 'react';
import styles from './styles.module.scss';
import { ThreatModalContext } from '.';

const ThreatIgnoreDetails = () => {
const { threat } = useContext( ThreatModalContext );

if ( ! threat?.status || [ 'ignored', 'fixed' ].includes( threat.status ) ) {
return null;
}

const codeableURL = getRedirectUrl( 'jetpack-protect-codeable-referral' );

return (
<div className={ styles.section }>
<Text variant="title-small">
{ __( 'Do you really want to ignore this threat?', 'jetpack' ) }
</Text>
<Text>
{ /* TODO: Ensure we only direct supported site to Codeable */ }
{ createInterpolateElement(
__(
'By choosing to ignore this threat, you acknowledge that you have reviewed the detected code. You are accepting the risks of maintaining a potentially malicious or vulnerable file on your site. If you are unsure, please request an estimate with <codeableLink>Codeable</codeableLink>.',
'jetpack'
),
{
codeableLink: <Button variant="link" isExternalLink={ true } href={ codeableURL } />,
}
) }
</Text>
</div>
);
};

export default ThreatIgnoreDetails;
Loading
Loading