diff --git a/app/components/UI/BlockaidBanner/BlockaidBanner.stories.tsx b/app/components/UI/BlockaidBanner/BlockaidBanner.stories.tsx index e1b5d3e4b407..bfbb4988e6bb 100644 --- a/app/components/UI/BlockaidBanner/BlockaidBanner.stories.tsx +++ b/app/components/UI/BlockaidBanner/BlockaidBanner.stories.tsx @@ -34,12 +34,6 @@ export const getBlockaidBannerStoryProps = (): BlockaidBannerProps => { storybookPropsGroupID, ); - const attackDetails = text( - 'attackDetails', - 'Sample Attack Details', - storybookPropsGroupID, - ); - return { severity: severitySelector, title, @@ -51,8 +45,11 @@ export const getBlockaidBannerStoryProps = (): BlockaidBannerProps => { }, onClose: () => console.log('closeButton clicked!'), attackType: 'raw_signature_farming', - attackDetails, flagType: 'malicious', + features: [ + 'Operator is an EOA', + 'Operator is untrusted according to previous activity', + ], }; }; diff --git a/app/components/UI/BlockaidBanner/BlockaidBanner.test.tsx b/app/components/UI/BlockaidBanner/BlockaidBanner.test.tsx index a7158dc010c7..4a390fed20f1 100644 --- a/app/components/UI/BlockaidBanner/BlockaidBanner.test.tsx +++ b/app/components/UI/BlockaidBanner/BlockaidBanner.test.tsx @@ -1,41 +1,22 @@ import React from 'react'; import { fireEvent, render } from '@testing-library/react-native'; import BlockaidBanner from './BlockaidBanner'; -import { Text } from 'react-native-svg'; -import ListItem from '../../../components/Base/ListItem'; -import { FlatList } from 'react-native-gesture-handler'; -import FontAwesome5Icon from 'react-native-vector-icons/FontAwesome5'; -import { StyleSheet } from 'react-native'; describe('BlockaidBanner', () => { - const listItems = [ - { - title: 'attack_description_1', - description: 'We found attack vectors in this request', - }, - { - title: 'attack_description_2', - description: 'This request shows a fake token name and icon.', - }, - { - title: 'attack_description_3', - description: - 'If you approve this request, a third party known for scams might take all your assets.', - }, + const mockFeatures = [ + 'We found attack vectors in this request', + 'This request shows a fake token name and icon.', + 'If you approve this request, a third party known for scams might take all your assets.', + 'Operator is an EOA', + 'Operator is untrusted according to previous activity', ]; - const styles = StyleSheet.create({ - wrapper: { - padding: 15, - }, - }); - it('should render correctly', () => { const wrapper = render( , ); @@ -47,7 +28,7 @@ describe('BlockaidBanner', () => { , ); @@ -68,7 +49,7 @@ describe('BlockaidBanner', () => { , ); @@ -78,51 +59,12 @@ describe('BlockaidBanner', () => { ).toBeDefined(); }); - it('should render correctly with string attack details', async () => { - const wrapper = render( - , - ); - - expect(wrapper).toMatchSnapshot(); - expect(await wrapper.queryByTestId('accordion-header')).toBeDefined(); - expect( - await wrapper.queryByText('This is a string attack details'), - ).toBeNull(); - fireEvent.press(await wrapper.getByText('See details')); - expect( - await wrapper.getByText('This is a string attack details'), - ).toBeDefined(); - }); - it('should render correctly with list attack details', async () => { const wrapper = render( - ( - - - - - - - {item.description} - - - - )} - keyExtractor={(item) => item.title} - /> - - } + features={mockFeatures} />, ); @@ -146,5 +88,11 @@ describe('BlockaidBanner', () => { 'If you approve this request, a third party known for scams might take all your assets.', ), ).toBeDefined(); + expect(await wrapper.queryByText('Operator is an EOA')).toBeDefined(); + expect( + await wrapper.queryByText( + 'Operator is untrusted according to previous activity', + ), + ).toBeDefined(); }); }); diff --git a/app/components/UI/BlockaidBanner/BlockaidBanner.tsx b/app/components/UI/BlockaidBanner/BlockaidBanner.tsx index f9ebc447b578..0c5917c925cb 100644 --- a/app/components/UI/BlockaidBanner/BlockaidBanner.tsx +++ b/app/components/UI/BlockaidBanner/BlockaidBanner.tsx @@ -2,15 +2,28 @@ import React from 'react'; import { strings } from '../../../../locales/i18n'; import { useTheme } from '@react-navigation/native'; import { AccordionHeaderHorizontalAlignment } from '../../../component-library/components/Accordions/Accordion'; -import { BlockaidBannerProps } from './BlockaidBanner.types'; +import { AttackType, BlockaidBannerProps } from './BlockaidBanner.types'; import { BannerAlertSeverity } from '../../../component-library/components/Banners/Banner'; import { DEFAULT_BANNERBASE_DESCRIPTION_TEXTVARIANT } from '../../../component-library/components/Banners/Banner/foundation/BannerBase/BannerBase.constants'; +import { FlatList } from 'react-native-gesture-handler'; +import { + REASON_DESCRIPTION_I18N_KEY_MAP, + SUSPICIOUS_TITLED_REQUESTS, +} from './utils'; import { StyleSheet } from 'react-native'; import Accordion from '../../../component-library/components/Accordions/Accordion/Accordion'; +import AttributionLink from './AttributionLink'; import BannerAlert from '../../../component-library/components/Banners/Banner/variants/BannerAlert/BannerAlert'; import FontAwesome5Icon from 'react-native-vector-icons/FontAwesome5'; +import ListItem from '../../../components/Base/ListItem'; import Text from '../../../component-library/components/Texts/Text/Text'; -import AttributionLink from './AttributionLink'; + +const getTitle = (attackType: AttackType) => { + if (SUSPICIOUS_TITLED_REQUESTS.indexOf(attackType) >= 0) { + return strings('blockaid_banner.suspicious_request_title'); + } + return strings('blockaid_banner.deceptive_request_title'); +}; const createStyles = (colors: any) => StyleSheet.create({ @@ -18,45 +31,15 @@ const createStyles = (colors: any) => shieldIcon: { marginRight: 5, color: colors.primary.default }, }); -const getTitleDescription = (attackType: string) => { - let title = strings('blockaid_banner.title'); - let description; - - switch (attackType) { - case 'raw_signature_farming': - title = strings('blockaid_banner.raw_signature_farming_title'); - description = strings( - 'blockaid_banner.raw_signature_farming_description', - ); - break; - case 'approval_farming': - case 'set_approval_for_all_farming': - case 'permit_farming': - description = strings('blockaid_banner.approval_farming_description'); - break; - case 'transfer_farming': - case 'transfer_from_farming': - case 'raw_native_token_transfer': - description = strings('blockaid_banner.transfer_farming_description'); - break; - case 'seaport_farming': - description = strings('blockaid_banner.seaport_farming_description'); - break; - case 'blur_farming': - description = strings('blockaid_banner.blur_farming_description'); - break; - case 'unfair_trade': - default: - description = strings('blockaid_banner.unfair_trade_description'); - break; - } +const getTitleDescription = (attackType: AttackType) => { + const title = getTitle(attackType); + const description = strings(REASON_DESCRIPTION_I18N_KEY_MAP[attackType]); return { title, description }; }; const BlockaidBanner = (bannerProps: BlockaidBannerProps) => { - const { flagType, attackType, onToggleShowDetails, attackDetails } = - bannerProps; + const { flagType, attackType, features, onToggleShowDetails } = bannerProps; const { colors } = useTheme(); const styles = createStyles(colors); @@ -64,15 +47,26 @@ const BlockaidBanner = (bannerProps: BlockaidBannerProps) => { const { title, description } = getTitleDescription(attackType); const renderAttackDetails = () => - typeof attackDetails === 'string' ? ( - - {attackDetails} - - ) : ( - attackDetails + features.length <= 0 ? null : ( + ( + + + + + + + {item.description} + + + + )} + keyExtractor={(item) => item.title} + /> ); - return ( + return flagType === 'benign' ? null : ( void; }; diff --git a/app/components/UI/BlockaidBanner/__snapshots__/BlockaidBanner.test.tsx.snap b/app/components/UI/BlockaidBanner/__snapshots__/BlockaidBanner.test.tsx.snap index e968a283d46d..f36d3d4f1d23 100644 --- a/app/components/UI/BlockaidBanner/__snapshots__/BlockaidBanner.test.tsx.snap +++ b/app/components/UI/BlockaidBanner/__snapshots__/BlockaidBanner.test.tsx.snap @@ -2,8 +2,16 @@ exports[`BlockaidBanner should render correctly 1`] = ` - - - } attackType="approval_farming" - flagType="malicious" - style={ - Object { - "backgroundColor": "#D7384719", - "borderColor": "#D73847", - "borderLeftWidth": 4, - "borderRadius": 4, - "flexDirection": "row", - "padding": 12, - "paddingLeft": 8, - } + features={ + Array [ + "We found attack vectors in this request", + "This request shows a fake token name and icon.", + "If you approve this request, a third party known for scams might take all your assets.", + "Operator is an EOA", + "Operator is untrusted according to previous activity", + ] } - testID="banneralert" -> - - - - - - This is a deceptive request - - - If you approve this request, a third party known for scams might take all your assets. - - - - See details - - - - - - - - ? - - Security advice by [object Object] - - - -`; - -exports[`BlockaidBanner should render correctly with string attack details 1`] = ` - = Object.freeze({ + rawSignatureFarming: 'raw_signature_farming', + approvalFarming: 'approval_farming', + setApprovalForAllFarming: 'set_approval_for_all_farming', + permitFarming: 'permit_farming', + transferFarming: 'transfer_farming', + transferFromFarming: 'transfer_from_farming', + rawNativeTokenTransfer: 'raw_native_token_transfer', + seaportFarming: 'seaport_farming', + blurFarming: 'blur_farming', + unfairTrade: 'unfair_trade', + tradeOrderFarming: 'trade_order_farming', + other: 'other', + maliciousDomain: 'malicious_domain', +}); + +export const REASON_DESCRIPTION_I18N_KEY_MAP = Object.freeze({ + [AttackTypes.rawSignatureFarming]: + 'blockaid_banner.raw_signature_farming_description', + [AttackTypes.approvalFarming]: 'blockaid_banner.approval_farming_description', + [AttackTypes.setApprovalForAllFarming]: + 'blockaid_banner.approval_farming_description', + [AttackTypes.permitFarming]: 'blockaid_banner.approval_farming_description', + [AttackTypes.transferFarming]: 'blockaid_banner.transfer_farming_description', + [AttackTypes.transferFromFarming]: + 'blockaid_banner.transfer_farming_description', + [AttackTypes.rawNativeTokenTransfer]: + 'blockaid_banner.transfer_farming_description', + [AttackTypes.seaportFarming]: 'blockaid_banner.seaport_farming_description', + [AttackTypes.blurFarming]: 'blockaid_banner.blur_farming_description', + [AttackTypes.unfairTrade]: 'blockaid_banner.unfair_trade_description', + [AttackTypes.tradeOrderFarming]: + 'blockaid_banner.trade_order_farming_description', + [AttackTypes.other]: 'blockaid_banner.other_description', + [AttackTypes.maliciousDomain]: 'blockaid_banner.malicious_domain_description', +}); + +export const SUSPICIOUS_TITLED_REQUESTS = ['raw_signature_farming']; diff --git a/locales/languages/en.json b/locales/languages/en.json index 10fb17da574c..2f6d55ae65ce 100644 --- a/locales/languages/en.json +++ b/locales/languages/en.json @@ -1,16 +1,19 @@ { "blockaid_banner": { - "title": "This is a deceptive request", + "deceptive_request_title": "This is a deceptive request", "attribution_link_name": "BlockAid", "attribution_link": "https://blockaid.me", "attribution": "Security advice by {{attributionLink}}", - "raw_signature_farming_title": "This is a suspicious request", + "suspicious_request_title": "This is a suspicious request", "raw_signature_farming_description": "If you approve this request, you might lose your assets.", "approval_farming_description": "If you approve this request, a third party known for scams might take all your assets.", "transfer_farming_description": "If you approve this request, a third party known for scams will take all your assets.", "seaport_farming_description": "If you approve this request, someone can steal your assets listed on OpenSea.", "blur_farming_description": "If you approve this request, someone can steal your assets listed on Blur.", - "unfair_trade": "If you approve this request, you might lose your assets." + "unfair_trade_description": "If you approve this request, you might lose your assets.", + "trade_order_farming_description": "If you approve this request, you might lose your assets.", + "other_description": "If you approve this request, you might lose your assets.", + "malicious_domain_description": "You're interacting with a malicious domain. If you approve this request, you might lose your assets." }, "date": { "months": {