mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-22 09:23:21 +01:00
Add Blockaid / PPOM Failed Request Security Alert (#20362)
* WIP blockaid: add request failed UI - proposed to update reason value. planning to update upon update * alphabetize * BlockaidBannerAlert: update tkeys based on reason * SecurityProviderBannerAlert: fix footer alignment * BlockaidBannerAlert: rm footer w failed resultType --------- Co-authored-by: legobeat <109787230+legobeat@users.noreply.github.com> Co-authored-by: Jyoti Puri <jyotipuri@gmail.com>
This commit is contained in:
parent
e9fbf8591f
commit
136ede5d4c
6
app/_locales/en/messages.json
generated
6
app/_locales/en/messages.json
generated
@ -565,6 +565,9 @@
|
||||
"blockaidDescriptionBlurFarming": {
|
||||
"message": "If you approve this request, someone can steal your assets listed on Blur."
|
||||
},
|
||||
"blockaidDescriptionFailed": {
|
||||
"message": "Because of an error, this request was not verified by the security provider. Proceed with caution."
|
||||
},
|
||||
"blockaidDescriptionMaliciousDomain": {
|
||||
"message": "You're interacting with a malicious domain. If you approve this request, you might lose your assets."
|
||||
},
|
||||
@ -580,6 +583,9 @@
|
||||
"blockaidTitleDeceptive": {
|
||||
"message": "This is a deceptive request"
|
||||
},
|
||||
"blockaidTitleMayNotBeSafe": {
|
||||
"message": "Request may not be safe"
|
||||
},
|
||||
"blockaidTitleSuspicious": {
|
||||
"message": "This is a suspicious request"
|
||||
},
|
||||
|
@ -49,8 +49,8 @@ export enum BlockaidReason {
|
||||
other = 'other',
|
||||
|
||||
// Locally defined
|
||||
notApplicable = 'NotApplicable',
|
||||
failed = 'Failed',
|
||||
notApplicable = 'NotApplicable',
|
||||
}
|
||||
|
||||
export enum BlockaidResultType {
|
||||
|
@ -59,7 +59,7 @@ exports[`Security Provider Banner Alert should match snapshot 1`] = `
|
||||
</details>
|
||||
</div>
|
||||
<p
|
||||
class="mm-box mm-text mm-text--body-sm mm-box--margin-top-2 mm-box--align-items-center mm-box--color-text-alternative"
|
||||
class="mm-box mm-text mm-text--body-sm mm-box--margin-top-3 mm-box--display-flex mm-box--align-items-center mm-box--color-text-alternative"
|
||||
>
|
||||
<span
|
||||
class="mm-box disclosure__summary--icon mm-icon mm-icon--size-sm mm-box--margin-inline-end-1 mm-box--display-inline-block mm-box--color-primary-default"
|
||||
|
@ -21,7 +21,7 @@ exports[`Blockaid Banner Alert should render 'danger' UI when securityAlertRespo
|
||||
If you approve this request, a third party known for scams might take all your assets.
|
||||
</p>
|
||||
<p
|
||||
class="mm-box mm-text mm-text--body-sm mm-box--margin-top-2 mm-box--align-items-center mm-box--color-text-alternative"
|
||||
class="mm-box mm-text mm-text--body-sm mm-box--margin-top-3 mm-box--display-flex mm-box--align-items-center mm-box--color-text-alternative"
|
||||
>
|
||||
<span
|
||||
class="mm-box disclosure__summary--icon mm-icon mm-icon--size-sm mm-box--margin-inline-end-1 mm-box--display-inline-block mm-box--color-primary-default"
|
||||
@ -46,6 +46,30 @@ exports[`Blockaid Banner Alert should render 'danger' UI when securityAlertRespo
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Blockaid Banner Alert should render 'warning' UI when securityAlertResponse.result_type is 'Failed 1`] = `
|
||||
<div
|
||||
class="box mm-banner-base mm-banner-alert mm-banner-alert--severity-warning box--margin-4 box--padding-3 box--padding-left-2 box--display-flex box--gap-2 box--flex-direction-row box--background-color-warning-muted box--rounded-sm"
|
||||
>
|
||||
<span
|
||||
class="mm-box mm-icon mm-icon--size-lg mm-box--display-inline-block mm-box--color-warning-default"
|
||||
style="mask-image: url('./images/icons/warning.svg');"
|
||||
/>
|
||||
<div>
|
||||
<h5
|
||||
class="mm-box mm-text mm-banner-base__title mm-text--body-lg-medium mm-box--color-text-default"
|
||||
data-testid="mm-banner-base-title"
|
||||
>
|
||||
This is a deceptive request
|
||||
</h5>
|
||||
<p
|
||||
class="mm-box mm-text mm-text--body-md mm-box--margin-top-2 mm-box--color-text-default"
|
||||
>
|
||||
If you approve this request, a third party known for scams might take all your assets.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Blockaid Banner Alert should render 'warning' UI when securityAlertResponse.result_type is 'Warning 1`] = `
|
||||
<div
|
||||
class="box mm-banner-base mm-banner-alert mm-banner-alert--severity-warning box--margin-4 box--padding-3 box--padding-left-2 box--display-flex box--gap-2 box--flex-direction-row box--background-color-warning-muted box--rounded-sm"
|
||||
@ -67,7 +91,7 @@ exports[`Blockaid Banner Alert should render 'warning' UI when securityAlertResp
|
||||
If you approve this request, a third party known for scams might take all your assets.
|
||||
</p>
|
||||
<p
|
||||
class="mm-box mm-text mm-text--body-sm mm-box--margin-top-2 mm-box--align-items-center mm-box--color-text-alternative"
|
||||
class="mm-box mm-text mm-text--body-sm mm-box--margin-top-3 mm-box--display-flex mm-box--align-items-center mm-box--color-text-alternative"
|
||||
>
|
||||
<span
|
||||
class="mm-box disclosure__summary--icon mm-icon mm-icon--size-sm mm-box--margin-inline-end-1 mm-box--display-inline-block mm-box--color-primary-default"
|
||||
@ -152,7 +176,7 @@ exports[`Blockaid Banner Alert should render details when provided 1`] = `
|
||||
</details>
|
||||
</div>
|
||||
<p
|
||||
class="mm-box mm-text mm-text--body-sm mm-box--margin-top-2 mm-box--align-items-center mm-box--color-text-alternative"
|
||||
class="mm-box mm-text mm-text--body-sm mm-box--margin-top-3 mm-box--display-flex mm-box--align-items-center mm-box--color-text-alternative"
|
||||
>
|
||||
<span
|
||||
class="mm-box disclosure__summary--icon mm-icon mm-icon--size-sm mm-box--margin-inline-end-1 mm-box--display-inline-block mm-box--color-primary-default"
|
||||
|
@ -21,6 +21,8 @@ const REASON_TO_DESCRIPTION_TKEY = Object.freeze({
|
||||
|
||||
[BlockaidReason.blurFarming]: 'blockaidDescriptionBlurFarming',
|
||||
|
||||
[BlockaidReason.failed]: 'blockaidDescriptionFailed',
|
||||
|
||||
[BlockaidReason.seaportFarming]: 'blockaidDescriptionSeaportFarming',
|
||||
|
||||
[BlockaidReason.maliciousDomain]: 'blockaidDescriptionMaliciousDomain',
|
||||
@ -36,8 +38,11 @@ const REASON_TO_DESCRIPTION_TKEY = Object.freeze({
|
||||
[BlockaidReason.other]: 'blockaidDescriptionMightLoseAssets',
|
||||
});
|
||||
|
||||
/** List of suspicious reason(s). Other reasons will be deemed as deceptive. */
|
||||
const SUSPCIOUS_REASON = [BlockaidReason.rawSignatureFarming];
|
||||
/** Reason to title translation key mapping. */
|
||||
const REASON_TO_TITLE_TKEY = Object.freeze({
|
||||
[BlockaidReason.failed]: 'blockaidTitleMayNotBeSafe',
|
||||
[BlockaidReason.rawSignatureFarming]: 'blockaidTitleSuspicious',
|
||||
});
|
||||
|
||||
function BlockaidBannerAlert({ securityAlertResponse }) {
|
||||
const t = useContext(I18nContext);
|
||||
@ -48,10 +53,7 @@ function BlockaidBannerAlert({ securityAlertResponse }) {
|
||||
|
||||
const { reason, result_type: resultType, features } = securityAlertResponse;
|
||||
|
||||
if (
|
||||
resultType === BlockaidResultType.Benign ||
|
||||
resultType === BlockaidResultType.Failed
|
||||
) {
|
||||
if (resultType === BlockaidResultType.Benign) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -69,21 +71,20 @@ function BlockaidBannerAlert({ securityAlertResponse }) {
|
||||
</Text>
|
||||
);
|
||||
|
||||
const isFailedResultType = resultType === BlockaidResultType.Failed;
|
||||
|
||||
const severity =
|
||||
resultType === BlockaidResultType.Malicious
|
||||
? Severity.Danger
|
||||
: Severity.Warning;
|
||||
|
||||
const title =
|
||||
SUSPCIOUS_REASON.indexOf(reason) > -1
|
||||
? t('blockaidTitleSuspicious')
|
||||
: t('blockaidTitleDeceptive');
|
||||
const title = t(REASON_TO_TITLE_TKEY[reason] || 'blockaidTitleDeceptive');
|
||||
|
||||
return (
|
||||
<SecurityProviderBannerAlert
|
||||
description={description}
|
||||
details={details}
|
||||
provider={SecurityProvider.Blockaid}
|
||||
provider={isFailedResultType ? null : SecurityProvider.Blockaid}
|
||||
severity={severity}
|
||||
title={title}
|
||||
/>
|
||||
|
@ -40,7 +40,7 @@ describe('Blockaid Banner Alert', () => {
|
||||
expect(container.querySelector('.mm-banner-alert')).toBeNull();
|
||||
});
|
||||
|
||||
it(`should not render when securityAlertResponse.result_type is '${BlockaidResultType.Failed}'`, () => {
|
||||
it(`should render '${Severity.Warning}' UI when securityAlertResponse.result_type is '${BlockaidResultType.Failed}`, () => {
|
||||
const { container } = renderWithLocalization(
|
||||
<BlockaidBannerAlert
|
||||
securityAlertResponse={{
|
||||
@ -49,8 +49,24 @@ describe('Blockaid Banner Alert', () => {
|
||||
}}
|
||||
/>,
|
||||
);
|
||||
const warningBannerAlert = container.querySelector(
|
||||
'.mm-banner-alert--severity-warning',
|
||||
);
|
||||
|
||||
expect(container.querySelector('.mm-banner-alert')).toBeNull();
|
||||
expect(warningBannerAlert).toBeInTheDocument();
|
||||
expect(warningBannerAlert).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it(`should render '${Severity.Warning}' UI when securityAlertResponse.result_type is '${BlockaidResultType.Warning}`, () => {
|
||||
const { container } = renderWithLocalization(
|
||||
<BlockaidBannerAlert securityAlertResponse={mockSecurityAlertResponse} />,
|
||||
);
|
||||
const warningBannerAlert = container.querySelector(
|
||||
'.mm-banner-alert--severity-warning',
|
||||
);
|
||||
|
||||
expect(warningBannerAlert).toBeInTheDocument();
|
||||
expect(warningBannerAlert).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it(`should render '${Severity.Danger}' UI when securityAlertResponse.result_type is '${BlockaidResultType.Malicious}`, () => {
|
||||
@ -70,18 +86,6 @@ describe('Blockaid Banner Alert', () => {
|
||||
expect(dangerBannerAlert).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it(`should render '${Severity.Warning}' UI when securityAlertResponse.result_type is '${BlockaidResultType.Warning}`, () => {
|
||||
const { container } = renderWithLocalization(
|
||||
<BlockaidBannerAlert securityAlertResponse={mockSecurityAlertResponse} />,
|
||||
);
|
||||
const warningBannerAlert = container.querySelector(
|
||||
'.mm-banner-alert--severity-warning',
|
||||
);
|
||||
|
||||
expect(warningBannerAlert).toBeInTheDocument();
|
||||
expect(warningBannerAlert).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render title, "This is a deceptive request"', () => {
|
||||
const { getByText } = renderWithLocalization(
|
||||
<BlockaidBannerAlert securityAlertResponse={mockSecurityAlertResponse} />,
|
||||
@ -90,7 +94,20 @@ describe('Blockaid Banner Alert', () => {
|
||||
expect(getByText('This is a deceptive request')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render title, "This is a suspicious request", when the reason is "raw_signature_farming"', () => {
|
||||
it(`should render title, "This is a suspicious request", when the reason is "${BlockaidReason.failed}"`, () => {
|
||||
const { getByText } = renderWithLocalization(
|
||||
<BlockaidBannerAlert
|
||||
securityAlertResponse={{
|
||||
...mockSecurityAlertResponse,
|
||||
reason: BlockaidReason.failed,
|
||||
}}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(getByText('Request may not be safe')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it(`should render title, "This is a suspicious request", when the reason is "${BlockaidReason.rawSignatureFarming}"`, () => {
|
||||
const { getByText } = renderWithLocalization(
|
||||
<BlockaidBannerAlert
|
||||
securityAlertResponse={{
|
||||
@ -131,6 +148,8 @@ describe('Blockaid Banner Alert', () => {
|
||||
'If you approve this request, a third party known for scams might take all your assets.',
|
||||
[BlockaidReason.blurFarming]:
|
||||
'If you approve this request, someone can steal your assets listed on Blur.',
|
||||
[BlockaidReason.failed]:
|
||||
'Because of an error, this request was not verified by the security provider. Proceed with caution.',
|
||||
[BlockaidReason.maliciousDomain]:
|
||||
"You're interacting with a malicious domain. If you approve this request, you might lose your assets.",
|
||||
[BlockaidReason.other]:
|
||||
|
@ -15,6 +15,7 @@ import { I18nContext } from '../../../contexts/i18n';
|
||||
import {
|
||||
AlignItems,
|
||||
Color,
|
||||
Display,
|
||||
IconColor,
|
||||
Severity,
|
||||
Size,
|
||||
@ -45,30 +46,33 @@ function SecurityProviderBannerAlert({
|
||||
</Disclosure>
|
||||
)}
|
||||
|
||||
<Text
|
||||
marginTop={2}
|
||||
alignItems={AlignItems.center}
|
||||
color={Color.textAlternative}
|
||||
variant={TextVariant.bodySm}
|
||||
>
|
||||
<Icon
|
||||
className="disclosure__summary--icon"
|
||||
color={IconColor.primaryDefault}
|
||||
name={IconName.SecurityTick}
|
||||
size={IconSize.Sm}
|
||||
marginInlineEnd={1}
|
||||
/>
|
||||
{t('securityProviderAdviceBy', [
|
||||
<ButtonLink
|
||||
key={`security-provider-button-link-${provider}`}
|
||||
size={Size.inherit}
|
||||
href={SECURITY_PROVIDER_CONFIG[provider].url}
|
||||
externalLink
|
||||
>
|
||||
{t(SECURITY_PROVIDER_CONFIG[provider].tKeyName)}
|
||||
</ButtonLink>,
|
||||
])}
|
||||
</Text>
|
||||
{provider && (
|
||||
<Text
|
||||
marginTop={3}
|
||||
display={Display.Flex}
|
||||
alignItems={AlignItems.center}
|
||||
color={Color.textAlternative}
|
||||
variant={TextVariant.bodySm}
|
||||
>
|
||||
<Icon
|
||||
className="disclosure__summary--icon"
|
||||
color={IconColor.primaryDefault}
|
||||
name={IconName.SecurityTick}
|
||||
size={IconSize.Sm}
|
||||
marginInlineEnd={1}
|
||||
/>
|
||||
{t('securityProviderAdviceBy', [
|
||||
<ButtonLink
|
||||
key={`security-provider-button-link-${provider}`}
|
||||
size={Size.inherit}
|
||||
href={SECURITY_PROVIDER_CONFIG[provider].url}
|
||||
externalLink
|
||||
>
|
||||
{t(SECURITY_PROVIDER_CONFIG[provider].tKeyName)}
|
||||
</ButtonLink>,
|
||||
])}
|
||||
</Text>
|
||||
)}
|
||||
</BannerAlert>
|
||||
);
|
||||
}
|
||||
@ -78,9 +82,6 @@ SecurityProviderBannerAlert.propTypes = {
|
||||
description: PropTypes.oneOfType([PropTypes.string, PropTypes.element])
|
||||
.isRequired,
|
||||
|
||||
/** Name of the security provider */
|
||||
provider: PropTypes.oneOfType(Object.values(SecurityProvider)).isRequired,
|
||||
|
||||
/** Severity level */
|
||||
severity: PropTypes.oneOfType([Severity.Danger, Severity.Warning]).isRequired,
|
||||
|
||||
@ -93,6 +94,9 @@ SecurityProviderBannerAlert.propTypes = {
|
||||
|
||||
/** Additional details to be displayed under the description */
|
||||
details: PropTypes.oneOfType([PropTypes.string, PropTypes.element]),
|
||||
|
||||
/** Name of the security provider */
|
||||
provider: PropTypes.oneOfType(Object.values(SecurityProvider)),
|
||||
};
|
||||
|
||||
export default SecurityProviderBannerAlert;
|
||||
|
@ -53,7 +53,10 @@ export default {
|
||||
control: {
|
||||
type: 'select',
|
||||
},
|
||||
options: [Object.values(SecurityProvider)],
|
||||
options: ['none', ...Object.values(SecurityProvider)],
|
||||
mapping: {
|
||||
none: null,
|
||||
},
|
||||
},
|
||||
severity: {
|
||||
control: {
|
||||
|
Loading…
Reference in New Issue
Block a user