1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-11-22 01:47:00 +01:00

Blockaid validation should be done on ethereum mainnet only (#20709)

This commit is contained in:
Jyoti Puri 2023-09-05 15:43:43 +05:30 committed by GitHub
parent 997d1359d2
commit 7906f18104
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 75 additions and 88 deletions

View File

@ -1,3 +1,4 @@
import { CHAIN_IDS } from '../../../../shared/constants/network';
import {
BlockaidReason,
BlockaidResultType,
@ -14,38 +15,48 @@ Object.defineProperty(globalThis, 'performance', {
value: () => undefined,
});
const createMiddleWare = (
usePPOM?: any,
securityAlertsEnabled?: boolean,
chainId?: string,
) => {
const usePPOMMock = jest.fn();
const ppomController = {
usePPOM: usePPOM || usePPOMMock,
};
const preferenceController = {
store: {
getState: () => ({
securityAlertsEnabled:
securityAlertsEnabled === undefined ?? securityAlertsEnabled,
}),
},
};
const networkController = {
state: { providerConfig: { chainId: chainId || CHAIN_IDS.MAINNET } },
};
return createPPOMMiddleware(
ppomController as any,
preferenceController as any,
networkController as any,
);
};
describe('PPOMMiddleware', () => {
it('should call ppomController.usePPOM for requests of type confirmation', async () => {
const useMock = jest.fn();
const ppomController = {
usePPOM: useMock,
};
const preferenceController = {
store: { getState: () => ({ securityAlertsEnabled: true }) },
};
const middlewareFunction = createPPOMMiddleware(
ppomController as any,
preferenceController as any,
);
const usePPOMMock = jest.fn();
const middlewareFunction = createMiddleWare(usePPOMMock);
await middlewareFunction(
{ method: 'eth_sendTransaction' },
undefined,
() => undefined,
);
expect(useMock).toHaveBeenCalledTimes(1);
expect(usePPOMMock).toHaveBeenCalledTimes(1);
});
it('should add validation response on confirmation requests', async () => {
const ppomController = {
usePPOM: async () => Promise.resolve('VALIDATION_RESULT'),
};
const preferenceController = {
store: { getState: () => ({ securityAlertsEnabled: true }) },
};
const middlewareFunction = createPPOMMiddleware(
ppomController as any,
preferenceController as any,
);
const usePPOM = async () => Promise.resolve('VALIDATION_RESULT');
const middlewareFunction = createMiddleWare(usePPOM);
const req = {
method: 'eth_sendTransaction',
securityAlertResponse: undefined,
@ -55,16 +66,19 @@ describe('PPOMMiddleware', () => {
});
it('should not do validation if user has not enabled preference', async () => {
const ppomController = {
usePPOM: async () => Promise.resolve('VALIDATION_RESULT'),
const usePPOM = async () => Promise.resolve('VALIDATION_RESULT');
const middlewareFunction = createMiddleWare(usePPOM, false);
const req = {
method: 'eth_sendTransaction',
securityAlertResponse: undefined,
};
const preferenceController = {
store: { getState: () => ({ securityAlertsEnabled: false }) },
};
const middlewareFunction = createPPOMMiddleware(
ppomController as any,
preferenceController as any,
);
await middlewareFunction(req, undefined, () => undefined);
expect(req.securityAlertResponse).toBeUndefined();
});
it('should not do validation if user is not on mainnet', async () => {
const usePPOM = async () => Promise.resolve('VALIDATION_RESULT');
const middlewareFunction = createMiddleWare(usePPOM, false, '0x2');
const req = {
method: 'eth_sendTransaction',
securityAlertResponse: undefined,
@ -74,18 +88,10 @@ describe('PPOMMiddleware', () => {
});
it('should set Failed type in response if usePPOM throw error', async () => {
const ppomController = {
usePPOM: async () => {
throw new Error('some error');
},
const usePPOM = async () => {
throw new Error('some error');
};
const preferenceController = {
store: { getState: () => ({ securityAlertsEnabled: true }) },
};
const middlewareFunction = createPPOMMiddleware(
ppomController as any,
preferenceController as any,
);
const middlewareFunction = createMiddleWare(usePPOM);
const req = {
method: 'eth_sendTransaction',
securityAlertResponse: undefined,
@ -103,18 +109,10 @@ describe('PPOMMiddleware', () => {
const ppom = {
validateJsonRpc: () => undefined,
};
const ppomController = {
usePPOM: async (callback: any) => {
callback(ppom);
},
const usePPOM = async (callback: any) => {
callback(ppom);
};
const preferenceController = {
store: { getState: () => ({ securityAlertsEnabled: true }) },
};
const middlewareFunction = createPPOMMiddleware(
ppomController as any,
preferenceController as any,
);
const middlewareFunction = createMiddleWare(usePPOM);
const nextMock = jest.fn();
await middlewareFunction(
{ method: 'eth_sendTransaction' },
@ -125,18 +123,10 @@ describe('PPOMMiddleware', () => {
});
it('should call next method when ppomController.usePPOM throws error', async () => {
const ppomController = {
usePPOM: async (_callback: any) => {
throw Error('Some error');
},
const usePPOM = async (_callback: any) => {
throw Error('Some error');
};
const preferenceController = {
store: { getState: () => ({ securityAlertsEnabled: true }) },
};
const middlewareFunction = createPPOMMiddleware(
ppomController as any,
preferenceController as any,
);
const middlewareFunction = createMiddleWare(usePPOM);
const nextMock = jest.fn();
await middlewareFunction(
{ method: 'eth_sendTransaction' },
@ -151,18 +141,10 @@ describe('PPOMMiddleware', () => {
const ppom = {
validateJsonRpc: validateMock,
};
const ppomController = {
usePPOM: async (callback: any) => {
callback(ppom);
},
const usePPOM = async (callback: any) => {
callback(ppom);
};
const preferenceController = {
store: { getState: () => ({ securityAlertsEnabled: true }) },
};
const middlewareFunction = createPPOMMiddleware(
ppomController as any,
preferenceController as any,
);
const middlewareFunction = createMiddleWare(usePPOM);
await middlewareFunction(
{ method: 'eth_sendTransaction' },
undefined,
@ -176,18 +158,10 @@ describe('PPOMMiddleware', () => {
const ppom = {
validateJsonRpc: validateMock,
};
const ppomController = {
usePPOM: async (callback: any) => {
callback(ppom);
},
const usePPOM = async (callback: any) => {
callback(ppom);
};
const preferenceController = {
store: { getState: () => ({ securityAlertsEnabled: true }) },
};
const middlewareFunction = createPPOMMiddleware(
ppomController as any,
preferenceController as any,
);
const middlewareFunction = createMiddleWare(usePPOM);
await middlewareFunction(
{ method: 'eth_someRequest' },
undefined,

View File

@ -1,10 +1,12 @@
import { PPOM } from '@blockaid/ppom_release';
import { PPOMController } from '@metamask/ppom-validator';
import { NetworkController } from '@metamask/network-controller';
import {
BlockaidReason,
BlockaidResultType,
} from '../../../../shared/constants/security-provider';
import { CHAIN_IDS } from '../../../../shared/constants/network';
import PreferencesController from '../../controllers/preferences';
const { sentry } = global as any;
@ -31,17 +33,24 @@ const ConfirmationMethods = Object.freeze([
*
* @param ppomController - Instance of PPOMController.
* @param preferencesController - Instance of PreferenceController.
* @param networkController - Instance of NetworkController.
* @returns PPOMMiddleware function.
*/
export function createPPOMMiddleware(
ppomController: PPOMController,
preferencesController: PreferencesController,
networkController: NetworkController,
) {
return async (req: any, _res: any, next: () => void) => {
try {
const securityAlertsEnabled =
preferencesController.store.getState()?.securityAlertsEnabled;
if (securityAlertsEnabled && ConfirmationMethods.includes(req.method)) {
const { chainId } = networkController.state.providerConfig;
if (
securityAlertsEnabled &&
ConfirmationMethods.includes(req.method) &&
chainId === CHAIN_IDS.MAINNET
) {
// eslint-disable-next-line require-atomic-updates
req.securityAlertResponse = await ppomController.usePPOM(
async (ppom: PPOM) => {

View File

@ -4076,7 +4076,11 @@ export default class MetamaskController extends EventEmitter {
///: BEGIN:ONLY_INCLUDE_IN(blockaid)
engine.push(
createPPOMMiddleware(this.ppomController, this.preferencesController),
createPPOMMiddleware(
this.ppomController,
this.preferencesController,
this.networkController,
),
);
///: END:ONLY_INCLUDE_IN