mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-11-26 12:29:06 +01:00
Improvement on approval pages (#18545)
This commit is contained in:
parent
467858fb78
commit
ca7f61126c
@ -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({
|
||||
}
|
||||
>
|
||||
<FormField
|
||||
inputRef={inputRef}
|
||||
dataTestId="custom-spending-cap-input"
|
||||
autoFocus
|
||||
wrappingLabelProps={{ as: 'div' }}
|
||||
id={
|
||||
decConversionGreaterThan(value, currentTokenBalance)
|
||||
|
@ -43,6 +43,7 @@ export default function FormField({
|
||||
id,
|
||||
inputProps,
|
||||
wrappingLabelProps,
|
||||
inputRef,
|
||||
}) {
|
||||
return (
|
||||
<div
|
||||
@ -110,6 +111,7 @@ export default function FormField({
|
||||
dataTestId={dataTestId}
|
||||
placeholder={placeholder}
|
||||
id={id}
|
||||
inputRef={inputRef}
|
||||
/>
|
||||
) : (
|
||||
<input
|
||||
@ -125,6 +127,7 @@ export default function FormField({
|
||||
data-testid={dataTestId}
|
||||
placeholder={placeholder}
|
||||
id={id}
|
||||
ref={inputRef}
|
||||
{...inputProps}
|
||||
/>
|
||||
)}
|
||||
@ -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,
|
||||
};
|
||||
|
@ -20,6 +20,7 @@ export default function NumericInput({
|
||||
placeholder,
|
||||
id,
|
||||
name,
|
||||
inputRef,
|
||||
}) {
|
||||
return (
|
||||
<div
|
||||
@ -48,6 +49,7 @@ export default function NumericInput({
|
||||
placeholder={placeholder}
|
||||
id={id}
|
||||
name={name}
|
||||
ref={inputRef}
|
||||
/>
|
||||
{detailText && (
|
||||
<Typography
|
||||
@ -80,4 +82,5 @@ NumericInput.propTypes = {
|
||||
* The id of the input element. Should be used with htmlFor with a label element.
|
||||
*/
|
||||
id: PropTypes.string,
|
||||
inputRef: PropTypes.object,
|
||||
};
|
||||
|
@ -11,6 +11,8 @@ import Button from '../../../components/ui/button';
|
||||
import SimulationErrorMessage from '../../../components/ui/simulation-error-message';
|
||||
import EditGasFeeButton from '../../../components/app/edit-gas-fee-button';
|
||||
import MultiLayerFeeMessage from '../../../components/app/multilayer-fee-message';
|
||||
import SecurityProviderBannerMessage from '../../../components/app/security-provider-banner-message/security-provider-banner-message';
|
||||
import { SECURITY_PROVIDER_MESSAGE_SEVERITIES } from '../../../components/app/security-provider-banner-message/security-provider-banner-message.constants';
|
||||
import {
|
||||
BLOCK_SIZES,
|
||||
JustifyContent,
|
||||
@ -555,6 +557,15 @@ export default class ConfirmApproveContent extends Component {
|
||||
'confirm-approve-content--full': showFullTxDetails,
|
||||
})}
|
||||
>
|
||||
{(txData?.securityProviderResponse?.flagAsDangerous !== undefined &&
|
||||
txData?.securityProviderResponse?.flagAsDangerous !==
|
||||
SECURITY_PROVIDER_MESSAGE_SEVERITIES.NOT_MALICIOUS) ||
|
||||
(txData?.securityProviderResponse &&
|
||||
Object.keys(txData.securityProviderResponse).length === 0) ? (
|
||||
<SecurityProviderBannerMessage
|
||||
securityProviderResponse={txData.securityProviderResponse}
|
||||
/>
|
||||
) : null}
|
||||
{warning && (
|
||||
<div className="confirm-approve-content__custom-nonce-warning">
|
||||
<ConfirmPageContainerWarning warning={warning} />
|
||||
|
@ -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();
|
||||
});
|
||||
});
|
||||
|
@ -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({
|
||||
<Box>
|
||||
<ConfirmPageContainerNavigation />
|
||||
</Box>
|
||||
{(txData?.securityProviderResponse?.flagAsDangerous !== undefined &&
|
||||
txData?.securityProviderResponse?.flagAsDangerous !==
|
||||
SECURITY_PROVIDER_MESSAGE_SEVERITIES.NOT_MALICIOUS) ||
|
||||
(txData?.securityProviderResponse &&
|
||||
Object.keys(txData.securityProviderResponse).length === 0) ? (
|
||||
<SecurityProviderBannerMessage
|
||||
securityProviderResponse={txData.securityProviderResponse}
|
||||
/>
|
||||
) : null}
|
||||
<Box
|
||||
paddingLeft={4}
|
||||
paddingRight={4}
|
||||
|
@ -278,4 +278,22 @@ describe('TokenAllowancePage', () => {
|
||||
|
||||
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(
|
||||
<TokenAllowance
|
||||
{...props}
|
||||
txData={{ ...props.txData, securityProviderResponse }}
|
||||
/>,
|
||||
store,
|
||||
);
|
||||
|
||||
expect(getByText(securityProviderResponse.reason)).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user