From 427b4f2108d112fb988ba7185e3601ff3c3fdb5c Mon Sep 17 00:00:00 2001 From: Danica Shen Date: Fri, 31 Mar 2023 11:00:44 +0200 Subject: [PATCH] =?UTF-8?q?fix(18194):=20Redirect=20to=20extension=20expan?= =?UTF-8?q?ded=20view=20when=20click=20back=20to=20sa=E2=80=A6=20(#18376)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(18194): Redirect to extension expanded view when click back to safety button * Bump phishing warning version --------- Co-authored-by: Dan J Miller --- app/scripts/metamask-controller.js | 11 +++++- app/scripts/platforms/extension.js | 25 +++++++++++--- app/scripts/platforms/extension.test.js | 30 ++++++++++++++++ package.json | 2 +- test/e2e/tests/phishing-detection.spec.js | 42 +++++++++++++++++++++++ yarn.lock | 10 +++--- 6 files changed, 108 insertions(+), 12 deletions(-) diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index a891bb924..bd1fe8300 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -3735,7 +3735,11 @@ export default class MetamaskController extends EventEmitter { phishingStream.on( 'data', createMetaRPCHandler( - { safelistPhishingDomain: this.safelistPhishingDomain.bind(this) }, + { + safelistPhishingDomain: this.safelistPhishingDomain.bind(this), + backToSafetyPhishingWarning: + this.backToSafetyPhishingWarning.bind(this), + }, phishingStream, ), ); @@ -4501,6 +4505,11 @@ export default class MetamaskController extends EventEmitter { return this.phishingController.bypass(hostname); } + async backToSafetyPhishingWarning() { + const extensionURL = this.platform.getExtensionURL(); + await this.platform.switchToAnotherURL(undefined, extensionURL); + } + /** * Locks MetaMask */ diff --git a/app/scripts/platforms/extension.js b/app/scripts/platforms/extension.js index 54088fa74..94f7482d7 100644 --- a/app/scripts/platforms/extension.js +++ b/app/scripts/platforms/extension.js @@ -77,11 +77,7 @@ export default class ExtensionPlatform { return version; } - openExtensionInBrowser( - route = null, - queryString = null, - keepWindowOpen = false, - ) { + getExtensionURL(route = null, queryString = null) { let extensionURL = browser.runtime.getURL('home.html'); if (route) { @@ -92,7 +88,22 @@ export default class ExtensionPlatform { extensionURL += `?${queryString}`; } + return extensionURL; + } + + openExtensionInBrowser( + route = null, + queryString = null, + keepWindowOpen = false, + ) { + const extensionURL = this.getExtensionURL( + route, + queryString, + keepWindowOpen, + ); + this.openTab({ url: extensionURL }); + if ( getEnvironmentType() !== ENVIRONMENT_TYPE_BACKGROUND && !keepWindowOpen @@ -153,6 +164,10 @@ export default class ExtensionPlatform { return tab; } + async switchToAnotherURL(tabId, url) { + await browser.tabs.update(tabId, { url }); + } + async closeTab(tabId) { await browser.tabs.remove(tabId); } diff --git a/app/scripts/platforms/extension.test.js b/app/scripts/platforms/extension.test.js index 1b2067d78..27cc0e8b9 100644 --- a/app/scripts/platforms/extension.test.js +++ b/app/scripts/platforms/extension.test.js @@ -1,10 +1,14 @@ import browser from 'webextension-polyfill'; import ExtensionPlatform from './extension'; +const TEST_URL = + 'chrome-extension://jjlgkphpeekojaidfeknpknnimdbleaf/home.html'; + jest.mock('webextension-polyfill', () => { return { runtime: { getManifest: jest.fn(), + getURL: jest.fn(), }, }; }); @@ -91,4 +95,30 @@ describe('extension platform', () => { ); }); }); + + describe('getExtensionURL', () => { + let extensionPlatform; + beforeEach(() => { + browser.runtime.getURL.mockReturnValue(TEST_URL); + extensionPlatform = new ExtensionPlatform(); + }); + + it('should return URL itself if no route or queryString is provided', () => { + expect(extensionPlatform.getExtensionURL()).toStrictEqual(TEST_URL); + }); + + it('should return URL with route when provided', () => { + const TEST_ROUTE = 'test-route'; + expect(extensionPlatform.getExtensionURL(TEST_ROUTE)).toStrictEqual( + `${TEST_URL}#${TEST_ROUTE}`, + ); + }); + + it('should return URL with queryString when provided', () => { + const QUERY_STRING = 'name=ferret'; + expect( + extensionPlatform.getExtensionURL(null, QUERY_STRING), + ).toStrictEqual(`${TEST_URL}?${QUERY_STRING}`); + }); + }); }); diff --git a/package.json b/package.json index 35ed90bf9..2689c5ec6 100644 --- a/package.json +++ b/package.json @@ -371,7 +371,7 @@ "@metamask/eslint-config-nodejs": "^9.0.0", "@metamask/eslint-config-typescript": "^9.0.1", "@metamask/forwarder": "^1.1.0", - "@metamask/phishing-warning": "^2.0.1", + "@metamask/phishing-warning": "^2.1.0", "@metamask/test-dapp": "^5.6.0", "@sentry/cli": "^1.58.0", "@storybook/addon-a11y": "^6.5.13", diff --git a/test/e2e/tests/phishing-detection.spec.js b/test/e2e/tests/phishing-detection.spec.js index cc30a5ca0..c82645e1f 100644 --- a/test/e2e/tests/phishing-detection.spec.js +++ b/test/e2e/tests/phishing-detection.spec.js @@ -289,4 +289,46 @@ describe('Phishing Detection', function () { }, ); }); + + it('should open a new extension expanded view when clicking back to safety button', async function () { + await withFixtures( + { + fixtures: new FixtureBuilder().build(), + ganacheOptions, + title: this.test.title, + testSpecificMock: mockPhishingDetection, + dapp: true, + dappPaths: ['mock-page-with-disallowed-iframe'], + dappOptions: { + numberOfDapps: 2, + }, + failOnConsoleError: false, + }, + async ({ driver }) => { + await driver.navigate(); + await driver.fill('#password', 'correct horse battery staple'); + await driver.press('#password', driver.Key.ENTER); + await driver.openNewPage( + `http://localhost:8080?extensionUrl=${driver.extensionUrl}`, + ); + + const iframe = await driver.findElement('iframe'); + + await driver.switchToFrame(iframe); + await driver.clickElement({ + text: 'Open this warning in a new tab', + }); + await driver.switchToWindowWithTitle('MetaMask Phishing Detection'); + await driver.clickElement({ + text: 'Back to safety', + }); + + // Ensure we're redirected to wallet home page + const homePage = await driver.findElement('.home__main-view'); + const homePageDisplayed = await homePage.isDisplayed(); + + assert.equal(homePageDisplayed, true); + }, + ); + }); }); diff --git a/yarn.lock b/yarn.lock index f16c5ce3c..c770a116f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4143,9 +4143,9 @@ __metadata: languageName: node linkType: hard -"@metamask/phishing-warning@npm:^2.0.1": - version: 2.0.1 - resolution: "@metamask/phishing-warning@npm:2.0.1" +"@metamask/phishing-warning@npm:^2.1.0": + version: 2.1.0 + resolution: "@metamask/phishing-warning@npm:2.1.0" dependencies: "@metamask/design-tokens": ^1.6.0 "@metamask/post-message-stream": ^6.0.0 @@ -4156,7 +4156,7 @@ __metadata: pump: ^3.0.0 punycode: ^2.1.1 ses: ^0.18.1 - checksum: caa3e596c3a67188e457307b43724c89121d60734353922d369932093f8618f96465ba7613b194dc2c57754399783dcdf1777c900afeff21bd5137f02688b686 + checksum: d04b3f817deafa077028f2d235ae694fa772a5ee6a02fc73c6f1fed6dbd1a7491370a25b9484157835f9e1a1773e738a1306ce0c854604eba99af86f1624f453 languageName: node linkType: hard @@ -24218,7 +24218,7 @@ __metadata: "@metamask/obs-store": ^5.0.0 "@metamask/permission-controller": ^2.0.0 "@metamask/phishing-controller": ^2.0.0 - "@metamask/phishing-warning": ^2.0.1 + "@metamask/phishing-warning": ^2.1.0 "@metamask/post-message-stream": ^6.0.0 "@metamask/providers": ^10.2.1 "@metamask/rate-limit-controller": ^1.0.0