From a5e70cbd71a8f706ac8c049888039ae72c225d57 Mon Sep 17 00:00:00 2001 From: Jyoti Puri Date: Fri, 2 Dec 2022 21:08:12 +0530 Subject: [PATCH] Adding middleware to filter out duplicate requests from DAPP (#16730) --- .../lib/createDupeReqFilterMiddleware.js | 23 ++++++++++++++ .../lib/createDupeReqFilterMiddleware.test.js | 30 +++++++++++++++++++ app/scripts/metamask-controller.js | 5 ++++ 3 files changed, 58 insertions(+) create mode 100644 app/scripts/lib/createDupeReqFilterMiddleware.js create mode 100644 app/scripts/lib/createDupeReqFilterMiddleware.test.js diff --git a/app/scripts/lib/createDupeReqFilterMiddleware.js b/app/scripts/lib/createDupeReqFilterMiddleware.js new file mode 100644 index 000000000..556e71c18 --- /dev/null +++ b/app/scripts/lib/createDupeReqFilterMiddleware.js @@ -0,0 +1,23 @@ +import log from 'loglevel'; + +/** + * Returns a middleware that filters out requests already seen + * + * @returns {Function} + */ +export default function createDupeReqFilterMiddleware() { + const processedRequestId = []; + return function filterDuplicateRequestMiddleware( + /** @type {any} */ req, + /** @type {any} */ _res, + /** @type {Function} */ next, + /** @type {Function} */ end, + ) { + if (processedRequestId.indexOf(req.id) >= 0) { + log.info(`RPC request with id ${req.id} already seen.`); + return end(); + } + processedRequestId.push(req.id); + return next(); + }; +} diff --git a/app/scripts/lib/createDupeReqFilterMiddleware.test.js b/app/scripts/lib/createDupeReqFilterMiddleware.test.js new file mode 100644 index 000000000..a8e3cfcb9 --- /dev/null +++ b/app/scripts/lib/createDupeReqFilterMiddleware.test.js @@ -0,0 +1,30 @@ +import createDupeReqFilterMiddleware from './createDupeReqFilterMiddleware'; + +describe('createDupeReqFilterMiddleware', () => { + it('call function next if request is seen first time', () => { + const filterFn = createDupeReqFilterMiddleware(); + const request = { id: 1 }; + const nextMock = jest.fn(); + const endMock = jest.fn(); + + filterFn(request, undefined, nextMock, endMock); + + expect(nextMock).toBeCalledTimes(1); + expect(endMock).not.toBeCalled(); + }); + + it('call function end if request is seen second time', () => { + const filterFn = createDupeReqFilterMiddleware(); + const request = { id: 1 }; + const nextMock = jest.fn(); + const endMock = jest.fn(); + + filterFn(request, undefined, nextMock, endMock); + expect(nextMock).toBeCalledTimes(1); + expect(endMock).not.toBeCalled(); + + filterFn(request, undefined, nextMock, endMock); + expect(nextMock).toBeCalledTimes(1); + expect(endMock).toBeCalledTimes(1); + }); +}); diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 68df9b46c..d07f58b62 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -113,6 +113,7 @@ import { } from './detect-multiple-instances'; import ComposableObservableStore from './lib/ComposableObservableStore'; import AccountTracker from './lib/account-tracker'; +import createDupeReqFilterMiddleware from './lib/createDupeReqFilterMiddleware'; import createLoggerMiddleware from './lib/createLoggerMiddleware'; import { createMethodMiddleware, @@ -3730,6 +3731,10 @@ export default class MetamaskController extends EventEmitter { engine.emit('notification', message), ); + if (isManifestV3) { + engine.push(createDupeReqFilterMiddleware()); + } + // append origin to each request engine.push(createOriginMiddleware({ origin }));