mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-11-22 09:57:02 +01:00
Open sea security provider warning message (#17662)
* Warning message for the OpenSea security provider * Updated snapshots * Removed flask usage * Covered more test cases * Code refactor * Fixed errors * Code refactor * Fixed few issues * Covered more code with tests
This commit is contained in:
parent
6892ab2bff
commit
2acd51af2e
24
app/_locales/en/messages.json
generated
24
app/_locales/en/messages.json
generated
@ -2606,6 +2606,9 @@
|
||||
"openSea": {
|
||||
"message": "OpenSea (Beta)"
|
||||
},
|
||||
"openSeaNew": {
|
||||
"message": "OpenSea"
|
||||
},
|
||||
"optional": {
|
||||
"message": "Optional"
|
||||
},
|
||||
@ -2953,6 +2956,24 @@
|
||||
"replace": {
|
||||
"message": "replace"
|
||||
},
|
||||
"requestFlaggedAsMaliciousFallbackCopyReason": {
|
||||
"message": "The security provider has not shared additional details"
|
||||
},
|
||||
"requestFlaggedAsMaliciousFallbackCopyReasonTitle": {
|
||||
"message": "Request flagged as malicious"
|
||||
},
|
||||
"requestMayNotBeSafe": {
|
||||
"message": "Request may not be safe"
|
||||
},
|
||||
"requestMayNotBeSafeError": {
|
||||
"message": "The security provider didn't detect any known malicious activity, but it still may not be safe to continue."
|
||||
},
|
||||
"requestNotVerified": {
|
||||
"message": "Request not verified"
|
||||
},
|
||||
"requestNotVerifiedError": {
|
||||
"message": "Because of an error, this request was not verified by the security provider. Proceed with caution."
|
||||
},
|
||||
"requestsAwaitingAcknowledgement": {
|
||||
"message": "requests waiting to be acknowledged"
|
||||
},
|
||||
@ -4002,6 +4023,9 @@
|
||||
"thingsToKeep": {
|
||||
"message": "Things to keep in mind:"
|
||||
},
|
||||
"thisIsBasedOn": {
|
||||
"message": "This is based on information from "
|
||||
},
|
||||
"thisServiceIsExperimental": {
|
||||
"message": "This service is experimental"
|
||||
},
|
||||
|
@ -1,5 +1,8 @@
|
||||
import getFetchWithTimeout from '../../../shared/modules/fetch-with-timeout';
|
||||
import { MESSAGE_TYPE } from '../../../shared/constants/app';
|
||||
|
||||
const fetchWithTimeout = getFetchWithTimeout();
|
||||
|
||||
export async function securityProviderCheck(
|
||||
requestData,
|
||||
methodName,
|
||||
@ -47,7 +50,7 @@ export async function securityProviderCheck(
|
||||
};
|
||||
}
|
||||
|
||||
const response = await fetch(
|
||||
const response = await fetchWithTimeout(
|
||||
'https://eos9d7dmfj.execute-api.us-east-1.amazonaws.com/metamask/validate',
|
||||
{
|
||||
method: 'POST',
|
||||
|
@ -11,6 +11,8 @@ import Typography from '../../../ui/typography';
|
||||
import { TypographyVariant } from '../../../../helpers/constants/design-system';
|
||||
import DepositPopover from '../../deposit-popover/deposit-popover';
|
||||
|
||||
import SecurityProviderBannerMessage from '../../security-provider-banner-message/security-provider-banner-message';
|
||||
import { SECURITY_PROVIDER_MESSAGE_SEVERITIES } from '../../security-provider-banner-message/security-provider-banner-message.constants';
|
||||
import { ConfirmPageContainerSummary, ConfirmPageContainerWarning } from '.';
|
||||
|
||||
export default class ConfirmPageContainerContent extends Component {
|
||||
@ -55,6 +57,7 @@ export default class ConfirmPageContainerContent extends Component {
|
||||
toAddress: PropTypes.string,
|
||||
transactionType: PropTypes.string,
|
||||
isBuyableChain: PropTypes.bool,
|
||||
txData: PropTypes.object,
|
||||
};
|
||||
|
||||
state = {
|
||||
@ -166,6 +169,7 @@ export default class ConfirmPageContainerContent extends Component {
|
||||
toAddress,
|
||||
transactionType,
|
||||
isBuyableChain,
|
||||
txData,
|
||||
} = this.props;
|
||||
|
||||
const { t } = this.context;
|
||||
@ -187,6 +191,15 @@ export default class ConfirmPageContainerContent extends Component {
|
||||
{ethGasPriceWarning && (
|
||||
<ConfirmPageContainerWarning warning={ethGasPriceWarning} />
|
||||
)}
|
||||
{(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}
|
||||
<ConfirmPageContainerSummary
|
||||
className={classnames({
|
||||
'confirm-page-container-summary--border':
|
||||
|
@ -4,6 +4,7 @@ import configureMockStore from 'redux-mock-store';
|
||||
import { TransactionType } from '../../../../../shared/constants/transaction';
|
||||
import { renderWithProvider } from '../../../../../test/lib/render-helpers';
|
||||
import { TRANSACTION_ERROR_KEY } from '../../../../helpers/constants/error-keys';
|
||||
import { SECURITY_PROVIDER_MESSAGE_SEVERITIES } from '../../security-provider-banner-message/security-provider-banner-message.constants';
|
||||
import ConfirmPageContainerContent from './confirm-page-container-content.component';
|
||||
|
||||
describe('Confirm Page Container Content', () => {
|
||||
@ -47,6 +48,13 @@ describe('Confirm Page Container Content', () => {
|
||||
disabled: true,
|
||||
origin: 'http://localhost:4200',
|
||||
hideTitle: false,
|
||||
txData: {
|
||||
securityProviderResponse: {
|
||||
flagAsDangerous: '?',
|
||||
reason: 'Some reason...',
|
||||
reason_header: 'Some reason header...',
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
@ -126,4 +134,40 @@ describe('Confirm Page Container Content', () => {
|
||||
|
||||
expect(queryByText('Address Book Account 1')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render SecurityProviderBannerMessage component properly', () => {
|
||||
const { queryByText } = renderWithProvider(
|
||||
<ConfirmPageContainerContent {...props} />,
|
||||
store,
|
||||
);
|
||||
|
||||
expect(queryByText('Request not verified')).toBeInTheDocument();
|
||||
expect(
|
||||
queryByText(
|
||||
'Because of an error, this request was not verified by the security provider. Proceed with caution.',
|
||||
),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
queryByText('This is based on information from'),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should not render SecurityProviderBannerMessage component when flagAsDangerous is not malicious', () => {
|
||||
props.txData.securityProviderResponse = {
|
||||
flagAsDangerous: SECURITY_PROVIDER_MESSAGE_SEVERITIES.NOT_MALICIOUS,
|
||||
};
|
||||
|
||||
const { queryByText } = renderWithProvider(
|
||||
<ConfirmPageContainerContent {...props} />,
|
||||
store,
|
||||
);
|
||||
|
||||
expect(queryByText('Request not verified')).toBeNull();
|
||||
expect(
|
||||
queryByText(
|
||||
'Because of an error, this request was not verified by the security provider. Proceed with caution.',
|
||||
),
|
||||
).toBeNull();
|
||||
expect(queryByText('This is based on information from')).toBeNull();
|
||||
});
|
||||
});
|
||||
|
@ -86,9 +86,7 @@ const ConfirmPageContainer = (props) => {
|
||||
currentTransaction,
|
||||
supportsEIP1559,
|
||||
nativeCurrency,
|
||||
///: BEGIN:ONLY_INCLUDE_IN(flask)
|
||||
txData,
|
||||
///: END:ONLY_INCLUDE_IN(flask)
|
||||
assetStandard,
|
||||
isApprovalOrRejection,
|
||||
} = props;
|
||||
@ -223,6 +221,7 @@ const ConfirmPageContainer = (props) => {
|
||||
toAddress={toAddress}
|
||||
transactionType={currentTransaction.type}
|
||||
isBuyableChain={isBuyableChain}
|
||||
txData={txData}
|
||||
/>
|
||||
)}
|
||||
{shouldDisplayWarning && errorKey === INSUFFICIENT_FUNDS_ERROR_KEY && (
|
||||
@ -346,9 +345,7 @@ ConfirmPageContainer.propTypes = {
|
||||
dataComponent: PropTypes.node,
|
||||
dataHexComponent: PropTypes.node,
|
||||
detailsComponent: PropTypes.node,
|
||||
///: BEGIN:ONLY_INCLUDE_IN(flask)
|
||||
txData: PropTypes.object,
|
||||
///: END:ONLY_INCLUDE_IN(flask)
|
||||
tokenAddress: PropTypes.string,
|
||||
nonce: PropTypes.string,
|
||||
warning: PropTypes.string,
|
||||
|
@ -0,0 +1 @@
|
||||
export { default } from './security-provider-banner-message';
|
@ -0,0 +1,5 @@
|
||||
export const SECURITY_PROVIDER_MESSAGE_SEVERITIES = {
|
||||
NOT_MALICIOUS: 0,
|
||||
MALICIOUS: 1,
|
||||
NOT_SAFE: 2,
|
||||
};
|
@ -0,0 +1,74 @@
|
||||
import React, { useContext } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {
|
||||
Color,
|
||||
SEVERITIES,
|
||||
Size,
|
||||
TypographyVariant,
|
||||
} from '../../../helpers/constants/design-system';
|
||||
import { I18nContext } from '../../../../.storybook/i18n';
|
||||
import { BannerAlert, ButtonLink } from '../../component-library';
|
||||
import Typography from '../../ui/typography/typography';
|
||||
import { SECURITY_PROVIDER_MESSAGE_SEVERITIES } from './security-provider-banner-message.constants';
|
||||
|
||||
export default function SecurityProviderBannerMessage({
|
||||
securityProviderResponse,
|
||||
}) {
|
||||
const t = useContext(I18nContext);
|
||||
|
||||
let messageTitle;
|
||||
let messageText;
|
||||
let severity;
|
||||
|
||||
if (
|
||||
securityProviderResponse.flagAsDangerous ===
|
||||
SECURITY_PROVIDER_MESSAGE_SEVERITIES.MALICIOUS
|
||||
) {
|
||||
messageTitle =
|
||||
securityProviderResponse.reason_header === ''
|
||||
? t('requestFlaggedAsMaliciousFallbackCopyReasonTitle')
|
||||
: securityProviderResponse.reason_header;
|
||||
messageText =
|
||||
securityProviderResponse.reason === ''
|
||||
? t('requestFlaggedAsMaliciousFallbackCopyReason')
|
||||
: securityProviderResponse.reason;
|
||||
severity = SEVERITIES.DANGER;
|
||||
} else if (
|
||||
securityProviderResponse.flagAsDangerous ===
|
||||
SECURITY_PROVIDER_MESSAGE_SEVERITIES.NOT_SAFE
|
||||
) {
|
||||
messageTitle = t('requestMayNotBeSafe');
|
||||
messageText = t('requestMayNotBeSafeError');
|
||||
severity = SEVERITIES.WARNING;
|
||||
} else {
|
||||
messageTitle = t('requestNotVerified');
|
||||
messageText = t('requestNotVerifiedError');
|
||||
severity = SEVERITIES.WARNING;
|
||||
}
|
||||
|
||||
return (
|
||||
<BannerAlert
|
||||
marginTop={4}
|
||||
marginRight={4}
|
||||
marginLeft={4}
|
||||
title={messageTitle}
|
||||
severity={severity}
|
||||
>
|
||||
<Typography variant={TypographyVariant.H6}>{messageText}</Typography>
|
||||
<Typography variant={TypographyVariant.H7} color={Color.textAlternative}>
|
||||
{t('thisIsBasedOn')}
|
||||
<ButtonLink
|
||||
size={Size.inherit}
|
||||
href="https://opensea.io/"
|
||||
target="_blank"
|
||||
>
|
||||
{t('openSeaNew')}
|
||||
</ButtonLink>
|
||||
</Typography>
|
||||
</BannerAlert>
|
||||
);
|
||||
}
|
||||
|
||||
SecurityProviderBannerMessage.propTypes = {
|
||||
securityProviderResponse: PropTypes.object,
|
||||
};
|
@ -0,0 +1,189 @@
|
||||
import { fireEvent } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import configureMockStore from 'redux-mock-store';
|
||||
import { renderWithProvider } from '../../../../test/lib/render-helpers';
|
||||
import SecurityProviderBannerMessage from './security-provider-banner-message';
|
||||
import { SECURITY_PROVIDER_MESSAGE_SEVERITIES } from './security-provider-banner-message.constants';
|
||||
|
||||
describe('Security Provider Banner Message', () => {
|
||||
const store = configureMockStore()({});
|
||||
|
||||
const thisIsBasedOnText = 'This is based on information from';
|
||||
|
||||
it('should render SecurityProviderBannerMessage component properly when flagAsDangerous is malicious', () => {
|
||||
const securityProviderResponse = {
|
||||
flagAsDangerous: SECURITY_PROVIDER_MESSAGE_SEVERITIES.MALICIOUS,
|
||||
reason:
|
||||
'Approval is to an unverified smart contract known for stealing NFTs in the past.',
|
||||
reason_header: 'This could be a scam',
|
||||
};
|
||||
|
||||
const { getByText } = renderWithProvider(
|
||||
<SecurityProviderBannerMessage
|
||||
securityProviderResponse={securityProviderResponse}
|
||||
/>,
|
||||
store,
|
||||
);
|
||||
|
||||
expect(getByText(securityProviderResponse.reason)).toBeInTheDocument();
|
||||
expect(
|
||||
getByText(securityProviderResponse.reason_header),
|
||||
).toBeInTheDocument();
|
||||
expect(getByText(thisIsBasedOnText)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render SecurityProviderBannerMessage component properly when flagAsDangerous is not safe', () => {
|
||||
const securityProviderResponse = {
|
||||
flagAsDangerous: SECURITY_PROVIDER_MESSAGE_SEVERITIES.NOT_SAFE,
|
||||
reason: 'Some reason...',
|
||||
reason_header: 'Some reason header...',
|
||||
};
|
||||
|
||||
const requestMayNotBeSafe = 'Request may not be safe';
|
||||
const requestMayNotBeSafeError =
|
||||
"The security provider didn't detect any known malicious activity, but it still may not be safe to continue.";
|
||||
|
||||
const { getByText } = renderWithProvider(
|
||||
<SecurityProviderBannerMessage
|
||||
securityProviderResponse={securityProviderResponse}
|
||||
/>,
|
||||
store,
|
||||
);
|
||||
|
||||
expect(getByText(requestMayNotBeSafe)).toBeInTheDocument();
|
||||
expect(getByText(requestMayNotBeSafeError)).toBeInTheDocument();
|
||||
expect(getByText(thisIsBasedOnText)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render SecurityProviderBannerMessage component properly when flagAsDangerous is undefined', () => {
|
||||
const securityProviderResponse = {
|
||||
flagAsDangerous: '?',
|
||||
reason: 'Some reason...',
|
||||
reason_header: 'Some reason header...',
|
||||
};
|
||||
|
||||
const requestNotVerified = 'Request not verified';
|
||||
const requestNotVerifiedError =
|
||||
'Because of an error, this request was not verified by the security provider. Proceed with caution.';
|
||||
|
||||
const { getByText } = renderWithProvider(
|
||||
<SecurityProviderBannerMessage
|
||||
securityProviderResponse={securityProviderResponse}
|
||||
/>,
|
||||
store,
|
||||
);
|
||||
|
||||
expect(getByText(requestNotVerified)).toBeInTheDocument();
|
||||
expect(getByText(requestNotVerifiedError)).toBeInTheDocument();
|
||||
expect(getByText(thisIsBasedOnText)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render SecurityProviderBannerMessage component properly when securityProviderResponse is empty', () => {
|
||||
const securityProviderResponse = {};
|
||||
|
||||
const requestNotVerified = 'Request not verified';
|
||||
const requestNotVerifiedError =
|
||||
'Because of an error, this request was not verified by the security provider. Proceed with caution.';
|
||||
|
||||
const { getByText } = renderWithProvider(
|
||||
<SecurityProviderBannerMessage
|
||||
securityProviderResponse={securityProviderResponse}
|
||||
/>,
|
||||
store,
|
||||
);
|
||||
|
||||
expect(getByText(requestNotVerified)).toBeInTheDocument();
|
||||
expect(getByText(requestNotVerifiedError)).toBeInTheDocument();
|
||||
expect(getByText(thisIsBasedOnText)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should navigate to the OpenSea web page when clicked on the OpenSea button', () => {
|
||||
const securityProviderResponse = {
|
||||
flagAsDangerous: SECURITY_PROVIDER_MESSAGE_SEVERITIES.NOT_SAFE,
|
||||
reason: 'Some reason...',
|
||||
reason_header: 'Some reason header...',
|
||||
};
|
||||
|
||||
const { getByText } = renderWithProvider(
|
||||
<SecurityProviderBannerMessage
|
||||
securityProviderResponse={securityProviderResponse}
|
||||
/>,
|
||||
store,
|
||||
);
|
||||
|
||||
const link = getByText('OpenSea');
|
||||
|
||||
expect(link).toBeInTheDocument();
|
||||
|
||||
fireEvent.click(link);
|
||||
|
||||
expect(link.closest('a')).toHaveAttribute('href', 'https://opensea.io/');
|
||||
});
|
||||
|
||||
it('should render SecurityProviderBannerMessage component properly, with predefined reason message, when a request is malicious and there is no reason given', () => {
|
||||
const securityProviderResponse = {
|
||||
flagAsDangerous: SECURITY_PROVIDER_MESSAGE_SEVERITIES.MALICIOUS,
|
||||
reason: '',
|
||||
reason_header: 'Some reason header...',
|
||||
};
|
||||
|
||||
const reason = 'The security provider has not shared additional details';
|
||||
|
||||
const { getByText } = renderWithProvider(
|
||||
<SecurityProviderBannerMessage
|
||||
securityProviderResponse={securityProviderResponse}
|
||||
/>,
|
||||
store,
|
||||
);
|
||||
|
||||
expect(
|
||||
getByText(securityProviderResponse.reason_header),
|
||||
).toBeInTheDocument();
|
||||
expect(getByText(reason)).toBeInTheDocument();
|
||||
expect(getByText(thisIsBasedOnText)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render SecurityProviderBannerMessage component properly, with predefined reason_header message, when a request is malicious and there is no reason header given', () => {
|
||||
const securityProviderResponse = {
|
||||
flagAsDangerous: SECURITY_PROVIDER_MESSAGE_SEVERITIES.MALICIOUS,
|
||||
reason: 'Some reason...',
|
||||
reason_header: '',
|
||||
};
|
||||
|
||||
const reasonHeader = 'Request flagged as malicious';
|
||||
|
||||
const { getByText } = renderWithProvider(
|
||||
<SecurityProviderBannerMessage
|
||||
securityProviderResponse={securityProviderResponse}
|
||||
/>,
|
||||
store,
|
||||
);
|
||||
|
||||
expect(getByText(reasonHeader)).toBeInTheDocument();
|
||||
expect(getByText(securityProviderResponse.reason)).toBeInTheDocument();
|
||||
expect(getByText(thisIsBasedOnText)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render SecurityProviderBannerMessage component properly, with predefined reason and reason_header messages, when a request is malicious and there are no reason and reason header given', () => {
|
||||
const securityProviderResponse = {
|
||||
flagAsDangerous: SECURITY_PROVIDER_MESSAGE_SEVERITIES.MALICIOUS,
|
||||
reason: '',
|
||||
reason_header: '',
|
||||
};
|
||||
|
||||
const reasonHeader = 'Request flagged as malicious';
|
||||
|
||||
const reason = 'The security provider has not shared additional details';
|
||||
|
||||
const { getByText } = renderWithProvider(
|
||||
<SecurityProviderBannerMessage
|
||||
securityProviderResponse={securityProviderResponse}
|
||||
/>,
|
||||
store,
|
||||
);
|
||||
|
||||
expect(getByText(reasonHeader)).toBeInTheDocument();
|
||||
expect(getByText(reason)).toBeInTheDocument();
|
||||
expect(getByText(thisIsBasedOnText)).toBeInTheDocument();
|
||||
});
|
||||
});
|
@ -22,6 +22,8 @@ import { NETWORK_TYPES } from '../../../../shared/constants/network';
|
||||
import { Numeric } from '../../../../shared/modules/Numeric';
|
||||
import { EtherDenomination } from '../../../../shared/constants/common';
|
||||
import ConfirmPageContainerNavigation from '../confirm-page-container/confirm-page-container-navigation';
|
||||
import SecurityProviderBannerMessage from '../security-provider-banner-message/security-provider-banner-message';
|
||||
import { SECURITY_PROVIDER_MESSAGE_SEVERITIES } from '../security-provider-banner-message/security-provider-banner-message.constants';
|
||||
import SignatureRequestOriginalWarning from './signature-request-original-warning';
|
||||
|
||||
export default class SignatureRequestOriginal extends Component {
|
||||
@ -135,6 +137,15 @@ export default class SignatureRequestOriginal extends Component {
|
||||
|
||||
return (
|
||||
<div className="request-signature__body">
|
||||
{(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}
|
||||
<div className="request-signature__origin">
|
||||
<SiteOrigin
|
||||
siteOrigin={txData.msgParams.origin}
|
||||
|
@ -5,6 +5,7 @@ import { MESSAGE_TYPE } from '../../../../shared/constants/app';
|
||||
import mockState from '../../../../test/data/mock-state.json';
|
||||
import { renderWithProvider } from '../../../../test/lib/render-helpers';
|
||||
import configureStore from '../../../store/store';
|
||||
import { SECURITY_PROVIDER_MESSAGE_SEVERITIES } from '../security-provider-banner-message/security-provider-banner-message.constants';
|
||||
import SignatureRequestOriginal from '.';
|
||||
|
||||
const MOCK_SIGN_DATA = JSON.stringify({
|
||||
@ -115,4 +116,37 @@ describe('SignatureRequestOriginal', () => {
|
||||
expect(getByText('Message \\u202E test:')).toBeInTheDocument();
|
||||
expect(getByText('Hi, \\u202E Alice!')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render SecurityProviderBannerMessage component properly', () => {
|
||||
props.txData.securityProviderResponse = {
|
||||
flagAsDangerous: '?',
|
||||
reason: 'Some reason...',
|
||||
reason_header: 'Some reason header...',
|
||||
};
|
||||
render();
|
||||
expect(screen.getByText('Request not verified')).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText(
|
||||
'Because of an error, this request was not verified by the security provider. Proceed with caution.',
|
||||
),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText('This is based on information from'),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should not render SecurityProviderBannerMessage component when flagAsDangerous is not malicious', () => {
|
||||
props.txData.securityProviderResponse = {
|
||||
flagAsDangerous: SECURITY_PROVIDER_MESSAGE_SEVERITIES.NOT_MALICIOUS,
|
||||
};
|
||||
|
||||
render();
|
||||
expect(screen.queryByText('Request not verified')).toBeNull();
|
||||
expect(
|
||||
screen.queryByText(
|
||||
'Because of an error, this request was not verified by the security provider. Proceed with caution.',
|
||||
),
|
||||
).toBeNull();
|
||||
expect(screen.queryByText('This is based on information from')).toBeNull();
|
||||
});
|
||||
});
|
||||
|
@ -16,6 +16,8 @@ import { formatMessageParams } from '../../../../shared/modules/siwe';
|
||||
import { Icon } from '../../component-library/icon/icon';
|
||||
import { IconColor } from '../../../helpers/constants/design-system';
|
||||
|
||||
import SecurityProviderBannerMessage from '../security-provider-banner-message/security-provider-banner-message';
|
||||
import { SECURITY_PROVIDER_MESSAGE_SEVERITIES } from '../security-provider-banner-message/security-provider-banner-message.constants';
|
||||
import Header from './signature-request-siwe-header';
|
||||
import Message from './signature-request-siwe-message';
|
||||
|
||||
@ -88,6 +90,15 @@ export default function SignatureRequestSIWE({
|
||||
isSIWEDomainValid={isSIWEDomainValid}
|
||||
subjectMetadata={targetSubjectMetadata}
|
||||
/>
|
||||
{(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}
|
||||
<Message data={formatMessageParams(parsedMessage, t)} />
|
||||
{!isMatchingAddress && (
|
||||
<ActionableMessage
|
||||
|
@ -24,6 +24,10 @@
|
||||
&__reject-all-button {
|
||||
margin-top: -15px;
|
||||
}
|
||||
|
||||
&__origin {
|
||||
margin-top: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.signature-request-header {
|
||||
|
@ -19,6 +19,8 @@ import { NETWORK_TYPES } from '../../../../shared/constants/network';
|
||||
import { Numeric } from '../../../../shared/modules/Numeric';
|
||||
import { EtherDenomination } from '../../../../shared/constants/common';
|
||||
import ConfirmPageContainerNavigation from '../confirm-page-container/confirm-page-container-navigation';
|
||||
import SecurityProviderBannerMessage from '../security-provider-banner-message/security-provider-banner-message';
|
||||
import { SECURITY_PROVIDER_MESSAGE_SEVERITIES } from '../security-provider-banner-message/security-provider-banner-message.constants';
|
||||
import Footer from './signature-request-footer';
|
||||
import Message from './signature-request-message';
|
||||
|
||||
@ -225,6 +227,15 @@ export default class SignatureRequest extends PureComponent {
|
||||
/>
|
||||
</div>
|
||||
<div className="signature-request-content">
|
||||
{(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}
|
||||
<div className="signature-request__origin">
|
||||
<SiteOrigin
|
||||
siteOrigin={origin}
|
||||
|
@ -3,6 +3,7 @@ import { fireEvent } from '@testing-library/react';
|
||||
import configureMockStore from 'redux-mock-store';
|
||||
import mockState from '../../../../test/data/mock-state.json';
|
||||
import { renderWithProvider } from '../../../../test/lib/render-helpers';
|
||||
import { SECURITY_PROVIDER_MESSAGE_SEVERITIES } from '../security-provider-banner-message/security-provider-banner-message.constants';
|
||||
import SignatureRequest from './signature-request.component';
|
||||
|
||||
describe('Signature Request Component', () => {
|
||||
@ -275,5 +276,88 @@ describe('Signature Request Component', () => {
|
||||
|
||||
expect(getByText('Reject 2 requests')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render SecurityProviderBannerMessage component properly', () => {
|
||||
const msgParams = {
|
||||
data: JSON.stringify(messageData),
|
||||
version: 'V4',
|
||||
origin: 'test',
|
||||
};
|
||||
|
||||
const { queryByText } = renderWithProvider(
|
||||
<SignatureRequest
|
||||
hardwareWalletRequiresConnection={false}
|
||||
clearConfirmTransaction={() => undefined}
|
||||
cancel={() => undefined}
|
||||
cancelAll={() => undefined}
|
||||
mostRecentOverviewPage="/"
|
||||
showRejectTransactionsConfirmationModal={() => undefined}
|
||||
history={{ push: '/' }}
|
||||
sign={() => undefined}
|
||||
txData={{
|
||||
msgParams,
|
||||
securityProviderResponse: {
|
||||
flagAsDangerous: '?',
|
||||
reason: 'Some reason...',
|
||||
reason_header: 'Some reason header...',
|
||||
},
|
||||
}}
|
||||
fromAccount={{ address: fromAddress }}
|
||||
provider={{ type: 'rpc' }}
|
||||
unapprovedMessagesCount={2}
|
||||
/>,
|
||||
store,
|
||||
);
|
||||
|
||||
expect(queryByText('Request not verified')).toBeInTheDocument();
|
||||
expect(
|
||||
queryByText(
|
||||
'Because of an error, this request was not verified by the security provider. Proceed with caution.',
|
||||
),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
queryByText('This is based on information from'),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should not render SecurityProviderBannerMessage component when flagAsDangerous is not malicious', () => {
|
||||
const msgParams = {
|
||||
data: JSON.stringify(messageData),
|
||||
version: 'V4',
|
||||
origin: 'test',
|
||||
};
|
||||
|
||||
const { queryByText } = renderWithProvider(
|
||||
<SignatureRequest
|
||||
hardwareWalletRequiresConnection={false}
|
||||
clearConfirmTransaction={() => undefined}
|
||||
cancel={() => undefined}
|
||||
cancelAll={() => undefined}
|
||||
mostRecentOverviewPage="/"
|
||||
showRejectTransactionsConfirmationModal={() => undefined}
|
||||
history={{ push: '/' }}
|
||||
sign={() => undefined}
|
||||
txData={{
|
||||
msgParams,
|
||||
securityProviderResponse: {
|
||||
flagAsDangerous:
|
||||
SECURITY_PROVIDER_MESSAGE_SEVERITIES.NOT_MALICIOUS,
|
||||
},
|
||||
}}
|
||||
fromAccount={{ address: fromAddress }}
|
||||
provider={{ type: 'rpc' }}
|
||||
unapprovedMessagesCount={2}
|
||||
/>,
|
||||
store,
|
||||
);
|
||||
|
||||
expect(queryByText('Request not verified')).toBeNull();
|
||||
expect(
|
||||
queryByText(
|
||||
'Because of an error, this request was not verified by the security provider. Proceed with caution.',
|
||||
),
|
||||
).toBeNull();
|
||||
expect(queryByText('This is based on information from')).toBeNull();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user