From ca7f61126cd259891560b51622de2517055f5478 Mon Sep 17 00:00:00 2001 From: Jyoti Puri Date: Thu, 13 Apr 2023 22:54:33 +0530 Subject: [PATCH] Improvement on approval pages (#18545) --- .../custom-spending-cap/custom-spending-cap.js | 14 ++++++++++++-- ui/components/ui/form-field/form-field.js | 7 +++++++ .../numeric-input/numeric-input.component.js | 3 +++ .../confirm-approve-content.component.js | 11 +++++++++++ .../confirm-approve-content.component.test.js | 18 ++++++++++++++++++ ui/pages/token-allowance/token-allowance.js | 11 +++++++++++ .../token-allowance/token-allowance.test.js | 18 ++++++++++++++++++ 7 files changed, 80 insertions(+), 2 deletions(-) diff --git a/ui/components/app/custom-spending-cap/custom-spending-cap.js b/ui/components/app/custom-spending-cap/custom-spending-cap.js index 12f1ddce4..7f4a46c26 100644 --- a/ui/components/app/custom-spending-cap/custom-spending-cap.js +++ b/ui/components/app/custom-spending-cap/custom-spending-cap.js @@ -1,4 +1,4 @@ -import React, { useState, useContext, useEffect } from 'react'; +import React, { useState, useContext, useEffect, useRef } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import PropTypes from 'prop-types'; import classnames from 'classnames'; @@ -41,6 +41,7 @@ export default function CustomSpendingCap({ }) { const t = useContext(I18nContext); const dispatch = useDispatch(); + const inputRef = useRef(null); const value = useSelector(getCustomTokenAmount); @@ -139,6 +140,15 @@ export default function CustomSpendingCap({ passTheErrorText(error); }, [error, passTheErrorText]); + useEffect(() => { + if (inputRef.current) { + inputRef.current.focus({ + preventScroll: true, + }); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [inputRef.current]); + const chooseTooltipContentText = decConversionGreaterThan( value, currentTokenBalance, @@ -182,8 +192,8 @@ export default function CustomSpendingCap({ } > ) : ( )} @@ -285,4 +288,8 @@ FormField.propTypes = { * If used ensure the id prop is set on the input and a label element is present using htmlFor with the same id to ensure accessibility. */ wrappingLabelProps: PropTypes.object, + /** + * ref for input component + */ + inputRef: PropTypes.object, }; diff --git a/ui/components/ui/numeric-input/numeric-input.component.js b/ui/components/ui/numeric-input/numeric-input.component.js index e7ac094c9..8d16351a8 100644 --- a/ui/components/ui/numeric-input/numeric-input.component.js +++ b/ui/components/ui/numeric-input/numeric-input.component.js @@ -20,6 +20,7 @@ export default function NumericInput({ placeholder, id, name, + inputRef, }) { return (
{detailText && ( + {(txData?.securityProviderResponse?.flagAsDangerous !== undefined && + txData?.securityProviderResponse?.flagAsDangerous !== + SECURITY_PROVIDER_MESSAGE_SEVERITIES.NOT_MALICIOUS) || + (txData?.securityProviderResponse && + Object.keys(txData.securityProviderResponse).length === 0) ? ( + + ) : null} {warning && (
diff --git a/ui/pages/confirm-approve/confirm-approve-content/confirm-approve-content.component.test.js b/ui/pages/confirm-approve/confirm-approve-content/confirm-approve-content.component.test.js index 87f3a13f2..2cabbfd9b 100644 --- a/ui/pages/confirm-approve/confirm-approve-content/confirm-approve-content.component.test.js +++ b/ui/pages/confirm-approve/confirm-approve-content/confirm-approve-content.component.test.js @@ -325,4 +325,22 @@ describe('ConfirmApproveContent Component', () => { expect(container).toMatchSnapshot(); }); + + it('should render security provider response if transaction is malicious', () => { + const securityProviderResponse = { + flagAsDangerous: 1, + reason: + 'This has been flagged as potentially suspicious. If you sign, you could lose access to all of your NFTs and any funds or other assets in your wallet.', + reason_header: 'Warning', + }; + const { getByText } = renderComponent({ + ...props, + txData: { + ...props.txData, + securityProviderResponse, + }, + }); + + expect(getByText(securityProviderResponse.reason)).toBeInTheDocument(); + }); }); diff --git a/ui/pages/token-allowance/token-allowance.js b/ui/pages/token-allowance/token-allowance.js index ef1583ef0..7ee7fd887 100644 --- a/ui/pages/token-allowance/token-allowance.js +++ b/ui/pages/token-allowance/token-allowance.js @@ -67,6 +67,8 @@ import { ICON_NAMES, } from '../../components/component-library/icon/deprecated'; import LedgerInstructionField from '../../components/app/ledger-instruction-field/ledger-instruction-field'; +import { SECURITY_PROVIDER_MESSAGE_SEVERITIES } from '../../components/app/security-provider-banner-message/security-provider-banner-message.constants'; +import SecurityProviderBannerMessage from '../../components/app/security-provider-banner-message/security-provider-banner-message'; const ALLOWED_HOSTS = ['portfolio.metamask.io']; @@ -272,6 +274,15 @@ export default function TokenAllowance({ + {(txData?.securityProviderResponse?.flagAsDangerous !== undefined && + txData?.securityProviderResponse?.flagAsDangerous !== + SECURITY_PROVIDER_MESSAGE_SEVERITIES.NOT_MALICIOUS) || + (txData?.securityProviderResponse && + Object.keys(txData.securityProviderResponse).length === 0) ? ( + + ) : null} { expect(queryByText('Prior to clicking confirm:')).toBeNull(); }); + + it('should render security provider response if transaction is malicious', () => { + const securityProviderResponse = { + flagAsDangerous: 1, + reason: + 'This has been flagged as potentially suspicious. If you sign, you could lose access to all of your NFTs and any funds or other assets in your wallet.', + reason_header: 'Warning', + }; + const { getByText } = renderWithProvider( + , + store, + ); + + expect(getByText(securityProviderResponse.reason)).toBeInTheDocument(); + }); });