Skip to content

Commit

Permalink
feat: added disable dapp and connection (#1775)
Browse files Browse the repository at this point in the history
* feat: added disable dapp

* feat: added disable connection

* fix: title style

* fix: close popup

* chore: rm api

* fix: popup height

* feat: + changelog

---------

Co-authored-by: vvvvvv1vvvvvv <[email protected]>
  • Loading branch information
heisenberg-2077 and vvvvvv1vvvvvv authored Sep 28, 2023
1 parent 1986073 commit c2ccce5
Show file tree
Hide file tree
Showing 14 changed files with 355 additions and 21 deletions.
9 changes: 8 additions & 1 deletion _raw/locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,14 @@
"resend": "Retry",
"submitTx": "Submit Transaction",
"testnet": "Testnet",
"mainnet": "Mainnet"
"mainnet": "Mainnet",
"cancelTransaction": "Cancel Transaction",
"detectedMultipleRequestsFromThisDapp": "Detected multiple requests from this Dapp",
"cancelCurrentTransaction": "Cancel current transaction",
"cancelAll": "Cancel all {{count}} requests from Dapp",
"blockDappFromSendingRequests": "Block Dapp from sending requests for 10 min",
"cancelConnection": "Cancel connection",
"cancelCurrentConnection": "Cancel current connection"
},
"signTypedData": {
"signTypeDataOnChain": "Sign {{chain}} Typed Data",
Expand Down
2 changes: 2 additions & 0 deletions changeLogs/09225.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Supported 4 testnet, including Moonbase Alpha Testnet, KCC Testnet, IoTeX Testnet, Pulse V4 Testnet
- Support for block continuous signing from phishing Dapps
2 changes: 2 additions & 0 deletions changeLogs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import version09221 from './09221.md';
import version09222 from './09222.md';
import version09223 from './09223.md';
import version09224 from './09224.md';
import version09225 from './09225.md';

const version = process.env.release || '0';
const versionMap = {
Expand Down Expand Up @@ -92,6 +93,7 @@ const versionMap = {
'0.92.22': version09222,
'0.92.23': version09223,
'0.92.24': version09224,
'0.92.25': version09225,
};
export const getUpdateContent = () => {
return versionMap[version];
Expand Down
2 changes: 2 additions & 0 deletions changeLogs/zh_CN/09225.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- 支持4条测试网,包括 Moonbase Alpha Testnet,KCC Testnet,IoTeX Testnet,Pulse V4 Testnet
- 支持屏蔽钓鱼Dapp的连续签名
9 changes: 0 additions & 9 deletions src/background/controller/provider/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -595,15 +595,6 @@ class ProviderController extends BaseController {
'eth_sendRawTransaction',
[rawTx]
);
try {
openapiService.traceTx(
hash,
traceId || '',
chainItem?.serverId || ''
);
} catch (e) {
// DO nothing
}
} else {
hash = await openapiService.pushTx(
{
Expand Down
11 changes: 11 additions & 0 deletions src/background/controller/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3310,6 +3310,17 @@ export class WalletController extends BaseController {
};

updateNotificationWinProps = notificationService.updateNotificationWinProps;

checkNeedDisplayBlockedRequestApproval =
notificationService.checkNeedDisplayBlockedRequestApproval;

checkNeedDisplayCancelAllApproval =
notificationService.checkNeedDisplayCancelAllApproval;

blockedDapp = () => {
notificationService.blockedDapp();
this.rejectAllApprovals();
};
}

const wallet = new WalletController();
Expand Down
92 changes: 91 additions & 1 deletion src/background/service/notification.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,15 @@ type StatsData = {
// should only open one window, unfocus will close the current notification
class NotificationService extends Events {
currentApproval: Approval | null = null;
dappManager = new Map<
string,
{
lastRejectTimestamp: number;
lastRejectCount: number;
blockedTimestamp: number;
isBlocked: boolean;
}
>();
_approvals: Approval[] = [];
notifiWindowId: null | number = null;
isLocked = false;
Expand Down Expand Up @@ -175,6 +184,7 @@ class NotificationService extends Events {

const approval = this.currentApproval;

this.clearLastRejectDapp();
this.deleteApproval(approval);

if (this.approvals.length > 0) {
Expand All @@ -187,8 +197,8 @@ class NotificationService extends Events {
};

rejectApproval = async (err?: string, stay = false, isInternal = false) => {
this.addLastRejectDapp();
const approval = this.currentApproval;

if (this.approvals.length <= 1) {
await this.clear(stay); // TODO: FIXME
}
Expand All @@ -214,6 +224,19 @@ class NotificationService extends Events {
};

requestApproval = async (data, winProps?): Promise<any> => {
const origin = this.getOrigin(data);
if (origin) {
const dapp = this.dappManager.get(origin);
// is blocked and less 10 min
if (
dapp?.isBlocked &&
Date.now() - dapp.blockedTimestamp < 60 * 1000 * 10
) {
throw ethErrors.provider.userRejectedRequest(
'User rejected the request.'
);
}
}
const currentAccount = preferenceService.getCurrentAccount();
const reportExplain = (signingTxId?: string) => {
const signingTx = signingTxId
Expand Down Expand Up @@ -344,6 +367,7 @@ class NotificationService extends Events {
};

rejectAllApprovals = () => {
this.addLastRejectDapp();
this.approvals.forEach((approval) => {
approval.reject &&
approval.reject(
Expand Down Expand Up @@ -399,6 +423,72 @@ class NotificationService extends Events {
getStatsData = () => {
return this.statsData;
};

private addLastRejectDapp() {
// not Rabby dapp
if (this.currentApproval?.data?.params?.$ctx) return;
const origin = this.getOrigin();
if (!origin) {
return;
}
const dapp = this.dappManager.get(origin);
// same origin and less 1 min
if (dapp && Date.now() - dapp.lastRejectTimestamp < 60 * 1000) {
dapp.lastRejectCount = dapp.lastRejectCount + 1;
dapp.lastRejectTimestamp = Date.now();
} else {
this.dappManager.set(origin, {
lastRejectTimestamp: Date.now(),
lastRejectCount: 1,
blockedTimestamp: 0,
isBlocked: false,
});
}
}

private clearLastRejectDapp() {
const origin = this.getOrigin();
if (!origin) {
return;
}
this.dappManager.delete(origin);
}

checkNeedDisplayBlockedRequestApproval = () => {
const origin = this.getOrigin();
if (!origin) {
return false;
}
const dapp = this.dappManager.get(origin);
if (!dapp) return false;
// less 1 min and reject count more than 2 times
if (
Date.now() - dapp.lastRejectTimestamp < 60 * 1000 &&
dapp.lastRejectCount >= 2
) {
return true;
}
return false;
};
checkNeedDisplayCancelAllApproval = () => {
return this.approvals.length > 1;
};

blockedDapp = () => {
const origin = this.getOrigin();
if (!origin) {
return;
}
const dapp = this.dappManager.get(origin);
if (!dapp) return;

dapp.isBlocked = true;
dapp.blockedTimestamp = Date.now();
};

private getOrigin(data = this.currentApproval?.data) {
return data?.params.origin || data?.origin;
}
}

export default new NotificationService();
5 changes: 2 additions & 3 deletions src/ui/assets/approval/arrow-down-blue.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
37 changes: 34 additions & 3 deletions src/ui/views/Approval/components/Connect/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { useTranslation } from 'react-i18next';
import i18n from '@/i18n';
import { Chain } from 'background/service/openapi';
import { ChainSelector, Spin, FallbackSiteLogo } from 'ui/component';
import { useApproval, useWallet } from 'ui/utils';
import { useApproval, useCommonPopupView, useWallet } from 'ui/utils';
import {
CHAINS_ENUM,
CHAINS,
Expand All @@ -27,6 +27,7 @@ import UserListDrawer from './UserListDrawer';
import IconSuccess from 'ui/assets/success.svg';
import PQueue from 'p-queue';
import { SignTestnetPermission } from './SignTestnetPermission';
import { ReactComponent as ArrowDownSVG } from '@/ui/assets/approval/arrow-down-blue.svg';

interface ConnectProps {
params: any;
Expand Down Expand Up @@ -586,6 +587,26 @@ const Connect = ({ params: { icon, origin } }: ConnectProps) => {
setRuleDrawerVisible(true);
};

const [
displayBlockedRequestApproval,
setDisplayBlockedRequestApproval,
] = React.useState<boolean>(false);
const { activePopup, setData } = useCommonPopupView();

React.useEffect(() => {
wallet
.checkNeedDisplayBlockedRequestApproval()
.then(setDisplayBlockedRequestApproval);
}, []);

const activeCancelPopup = () => {
setData({
onCancel: handleCancel,
displayBlockedRequestApproval,
});
activePopup('CancelConnect');
};

return (
<Spin spinning={isLoading}>
<ConnectWrapper>
Expand Down Expand Up @@ -709,11 +730,21 @@ const Connect = ({ params: { icon, origin } }: ConnectProps) => {
<Button
type="primary"
ghost
className="rabby-btn-ghost"
className={clsx(
'rabby-btn-ghost',
'flex items-center justify-center gap-2'
)}
size="large"
onClick={handleCancel}
onClick={
displayBlockedRequestApproval
? activeCancelPopup
: handleCancel
}
>
{connectBtnStatus.cancelBtnText}
{displayBlockedRequestApproval && (
<ArrowDownSVG className="w-16" />
)}
</Button>
</div>
</Footer>
Expand Down
41 changes: 39 additions & 2 deletions src/ui/views/Approval/components/FooterBar/ActionsContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import React from 'react';
import { useTranslation } from 'react-i18next';
import { Account } from '@/background/service/preference';
import { Chain } from '@debank/common';
import { useCommonPopupView, useWallet } from '@/ui/utils';
import { ReactComponent as ArrowDownSVG } from '@/ui/assets/approval/arrow-down-blue.svg';

export interface Props {
onSubmit(): void;
Expand All @@ -20,7 +22,39 @@ export const ActionsContainer: React.FC<Pick<Props, 'onCancel'>> = ({
children,
onCancel,
}) => {
const wallet = useWallet();
const { t } = useTranslation();
const [
displayBlockedRequestApproval,
setDisplayBlockedRequestApproval,
] = React.useState(false);
const [
displayCancelAllApproval,
setDisplayCancelAllApproval,
] = React.useState(false);
const { activePopup, setData } = useCommonPopupView();

React.useEffect(() => {
wallet
.checkNeedDisplayBlockedRequestApproval()
.then(setDisplayBlockedRequestApproval);
wallet
.checkNeedDisplayCancelAllApproval()
.then(setDisplayCancelAllApproval);
}, []);

const displayPopup =
displayBlockedRequestApproval || displayCancelAllApproval;

const activeCancelPopup = () => {
setData({
onCancel,
displayBlockedRequestApproval,
displayCancelAllApproval,
});
activePopup('CancelApproval');
};

return (
<div className="flex gap-[12px] relative justify-end">
{children}
Expand All @@ -31,11 +65,14 @@ export const ActionsContainer: React.FC<Pick<Props, 'onCancel'>> = ({
'hover:bg-[#8697FF1A] active:bg-[#0000001A]',
'rounded-[8px]',
'before:content-none',
'z-10'
'z-10',
'flex items-center justify-center gap-2'
)}
onClick={onCancel}
onClick={displayPopup ? activeCancelPopup : onCancel}
>
{t('global.cancelButton')}

{displayPopup && <ArrowDownSVG className="w-16" />}
</Button>
</div>
);
Expand Down
Loading

0 comments on commit c2ccce5

Please sign in to comment.