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 { useDispatch, useSelector } from 'react-redux';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
@ -41,6 +41,7 @@ export default function CustomSpendingCap({
|
|||||||
}) {
|
}) {
|
||||||
const t = useContext(I18nContext);
|
const t = useContext(I18nContext);
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
const inputRef = useRef(null);
|
||||||
|
|
||||||
const value = useSelector(getCustomTokenAmount);
|
const value = useSelector(getCustomTokenAmount);
|
||||||
|
|
||||||
@ -139,6 +140,15 @@ export default function CustomSpendingCap({
|
|||||||
passTheErrorText(error);
|
passTheErrorText(error);
|
||||||
}, [error, passTheErrorText]);
|
}, [error, passTheErrorText]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (inputRef.current) {
|
||||||
|
inputRef.current.focus({
|
||||||
|
preventScroll: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [inputRef.current]);
|
||||||
|
|
||||||
const chooseTooltipContentText = decConversionGreaterThan(
|
const chooseTooltipContentText = decConversionGreaterThan(
|
||||||
value,
|
value,
|
||||||
currentTokenBalance,
|
currentTokenBalance,
|
||||||
@ -182,8 +192,8 @@ export default function CustomSpendingCap({
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<FormField
|
<FormField
|
||||||
|
inputRef={inputRef}
|
||||||
dataTestId="custom-spending-cap-input"
|
dataTestId="custom-spending-cap-input"
|
||||||
autoFocus
|
|
||||||
wrappingLabelProps={{ as: 'div' }}
|
wrappingLabelProps={{ as: 'div' }}
|
||||||
id={
|
id={
|
||||||
decConversionGreaterThan(value, currentTokenBalance)
|
decConversionGreaterThan(value, currentTokenBalance)
|
||||||
|
@ -43,6 +43,7 @@ export default function FormField({
|
|||||||
id,
|
id,
|
||||||
inputProps,
|
inputProps,
|
||||||
wrappingLabelProps,
|
wrappingLabelProps,
|
||||||
|
inputRef,
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
@ -110,6 +111,7 @@ export default function FormField({
|
|||||||
dataTestId={dataTestId}
|
dataTestId={dataTestId}
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
id={id}
|
id={id}
|
||||||
|
inputRef={inputRef}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<input
|
<input
|
||||||
@ -125,6 +127,7 @@ export default function FormField({
|
|||||||
data-testid={dataTestId}
|
data-testid={dataTestId}
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
id={id}
|
id={id}
|
||||||
|
ref={inputRef}
|
||||||
{...inputProps}
|
{...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.
|
* 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,
|
wrappingLabelProps: PropTypes.object,
|
||||||
|
/**
|
||||||
|
* ref for input component
|
||||||
|
*/
|
||||||
|
inputRef: PropTypes.object,
|
||||||
};
|
};
|
||||||
|
@ -20,6 +20,7 @@ export default function NumericInput({
|
|||||||
placeholder,
|
placeholder,
|
||||||
id,
|
id,
|
||||||
name,
|
name,
|
||||||
|
inputRef,
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
@ -48,6 +49,7 @@ export default function NumericInput({
|
|||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
id={id}
|
id={id}
|
||||||
name={name}
|
name={name}
|
||||||
|
ref={inputRef}
|
||||||
/>
|
/>
|
||||||
{detailText && (
|
{detailText && (
|
||||||
<Typography
|
<Typography
|
||||||
@ -80,4 +82,5 @@ NumericInput.propTypes = {
|
|||||||
* The id of the input element. Should be used with htmlFor with a label element.
|
* The id of the input element. Should be used with htmlFor with a label element.
|
||||||
*/
|
*/
|
||||||
id: PropTypes.string,
|
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 SimulationErrorMessage from '../../../components/ui/simulation-error-message';
|
||||||
import EditGasFeeButton from '../../../components/app/edit-gas-fee-button';
|
import EditGasFeeButton from '../../../components/app/edit-gas-fee-button';
|
||||||
import MultiLayerFeeMessage from '../../../components/app/multilayer-fee-message';
|
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 {
|
import {
|
||||||
BLOCK_SIZES,
|
BLOCK_SIZES,
|
||||||
JustifyContent,
|
JustifyContent,
|
||||||
@ -555,6 +557,15 @@ export default class ConfirmApproveContent extends Component {
|
|||||||
'confirm-approve-content--full': showFullTxDetails,
|
'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 && (
|
{warning && (
|
||||||
<div className="confirm-approve-content__custom-nonce-warning">
|
<div className="confirm-approve-content__custom-nonce-warning">
|
||||||
<ConfirmPageContainerWarning warning={warning} />
|
<ConfirmPageContainerWarning warning={warning} />
|
||||||
|
@ -325,4 +325,22 @@ describe('ConfirmApproveContent Component', () => {
|
|||||||
|
|
||||||
expect(container).toMatchSnapshot();
|
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,
|
ICON_NAMES,
|
||||||
} from '../../components/component-library/icon/deprecated';
|
} from '../../components/component-library/icon/deprecated';
|
||||||
import LedgerInstructionField from '../../components/app/ledger-instruction-field/ledger-instruction-field';
|
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'];
|
const ALLOWED_HOSTS = ['portfolio.metamask.io'];
|
||||||
|
|
||||||
@ -272,6 +274,15 @@ export default function TokenAllowance({
|
|||||||
<Box>
|
<Box>
|
||||||
<ConfirmPageContainerNavigation />
|
<ConfirmPageContainerNavigation />
|
||||||
</Box>
|
</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
|
<Box
|
||||||
paddingLeft={4}
|
paddingLeft={4}
|
||||||
paddingRight={4}
|
paddingRight={4}
|
||||||
|
@ -278,4 +278,22 @@ describe('TokenAllowancePage', () => {
|
|||||||
|
|
||||||
expect(queryByText('Prior to clicking confirm:')).toBeNull();
|
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