From c664eb722f6870594045fe865a9655fcbcdce748 Mon Sep 17 00:00:00 2001 From: Mat <63294765+matstyler@users.noreply.github.com> Date: Wed, 28 Feb 2024 23:24:37 +0100 Subject: [PATCH] :sparkles: feat: Encrypt/decrypt using MetaMask (#1109) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Motivation and context Implemented encrypt/decrypt functionalities using MetaMask. ## Does it fix any issue? https://linear.app/synpress/issue/SYN-63/encryptdecrypt - [x] I have performed a self-review of my code. - [x] If it is a core feature, I have added thorough e2e tests. **⚠️👆 Delete any section you see irrelevant before submitting the pull request 👆⚠️** ---
Generated summary > ### TL;DR > This pull request adds new methods to MetaMask class for adding new tokens, providing public encryption keys, and decrypting messages. It also includes new actions for encryption in the NotificationPage. > > ### What changed > - Added new methods `addNewToken()`, `providePublicEncryptionKey()`, and `decrypt()` to the MetaMask class. > - Added new actions for encryption in the NotificationPage. > - Created new files for encryption actions in the NotificationPage. > > ### How to test > 1. Click on the 'getEncryptionKeyButton' button to provide a public encryption key. > 2. Verify that the encryption key is displayed correctly. > 3. Encrypt and decrypt a message by following the steps provided in the test cases. > > ### Why make this change > - This change introduces new functionality to MetaMask for handling encryption tasks. > - The addition of encryption actions in the NotificationPage enhances the security features of the application. > - These changes improve the overall user experience and security of MetaMask.
--- wallets/metamask/src/metamask.ts | 32 ++++++++++++----- .../NotificationPage/actions/encryption.ts | 10 ++++++ .../pages/NotificationPage/actions/index.ts | 1 + .../src/pages/NotificationPage/page.ts | 14 ++++++++ .../pages/OnboardingPage/selectors/index.ts | 4 +-- .../getNotificationPageAndWaitForLoad.ts | 4 ++- .../test/e2e/metamask/encrypt.spec.ts | 34 +++++++++++++++++++ 7 files changed, 88 insertions(+), 11 deletions(-) create mode 100644 wallets/metamask/src/pages/NotificationPage/actions/encryption.ts create mode 100644 wallets/metamask/test/e2e/metamask/encrypt.spec.ts diff --git a/wallets/metamask/src/metamask.ts b/wallets/metamask/src/metamask.ts index 7268c0304..9e864f1bf 100644 --- a/wallets/metamask/src/metamask.ts +++ b/wallets/metamask/src/metamask.ts @@ -384,6 +384,30 @@ export class MetaMask { await this.settingsPage.disableEthSign() } + async addNewToken() { + if (!this.extensionId) { + throw NO_EXTENSION_ID_ERROR + } + + await this.notificationPage.addNewToken(this.extensionId) + } + + async providePublicEncryptionKey() { + if (!this.extensionId) { + throw NO_EXTENSION_ID_ERROR + } + + await this.notificationPage.providePublicEncryptionKey(this.extensionId) + } + + async decrypt() { + if (!this.extensionId) { + throw NO_EXTENSION_ID_ERROR + } + + await this.notificationPage.decryptMessage(this.extensionId) + } + /// ------------------------------------------- /// ---------- EXPERIMENTAL FEATURES ---------- /// ------------------------------------------- @@ -429,12 +453,4 @@ export class MetaMask { async closeTransactionDetails() { await this.homePage.closeTransactionDetails() } - - async addNewToken() { - if (!this.extensionId) { - throw NO_EXTENSION_ID_ERROR - } - - await this.notificationPage.addNewToken(this.extensionId) - } } diff --git a/wallets/metamask/src/pages/NotificationPage/actions/encryption.ts b/wallets/metamask/src/pages/NotificationPage/actions/encryption.ts new file mode 100644 index 000000000..365371806 --- /dev/null +++ b/wallets/metamask/src/pages/NotificationPage/actions/encryption.ts @@ -0,0 +1,10 @@ +import type { Page } from '@playwright/test' +import Selectors from '../selectors' + +export async function providePublicEncryptionKey(notificationPage: Page) { + await notificationPage.locator(Selectors.ActionFooter.confirmActionButton).click() +} + +export async function decryptMessage(notificationPage: Page) { + await notificationPage.locator(Selectors.ActionFooter.confirmActionButton).click() +} diff --git a/wallets/metamask/src/pages/NotificationPage/actions/index.ts b/wallets/metamask/src/pages/NotificationPage/actions/index.ts index d54f0c031..3a2f10500 100644 --- a/wallets/metamask/src/pages/NotificationPage/actions/index.ts +++ b/wallets/metamask/src/pages/NotificationPage/actions/index.ts @@ -5,3 +5,4 @@ export * from './approvePermission' export * from './transaction' export * from './network' export * from './token' +export * from './encryption' diff --git a/wallets/metamask/src/pages/NotificationPage/page.ts b/wallets/metamask/src/pages/NotificationPage/page.ts index 59e3bc13f..ebed5cced 100644 --- a/wallets/metamask/src/pages/NotificationPage/page.ts +++ b/wallets/metamask/src/pages/NotificationPage/page.ts @@ -5,7 +5,9 @@ import { type GasSetting, approvePermission, connectToDapp, + decryptMessage, network, + providePublicEncryptionKey, signSimpleMessage, signStructuredMessage, token, @@ -139,4 +141,16 @@ export class NotificationPage { await token.addNew(notificationPage) } + + async providePublicEncryptionKey(extensionId: string) { + const notificationPage = await getNotificationPageAndWaitForLoad(this.page.context(), extensionId) + + await providePublicEncryptionKey(notificationPage) + } + + async decryptMessage(extensionId: string) { + const notificationPage = await getNotificationPageAndWaitForLoad(this.page.context(), extensionId) + + await decryptMessage(notificationPage) + } } diff --git a/wallets/metamask/src/pages/OnboardingPage/selectors/index.ts b/wallets/metamask/src/pages/OnboardingPage/selectors/index.ts index 3fcc0ceb4..c681569c8 100644 --- a/wallets/metamask/src/pages/OnboardingPage/selectors/index.ts +++ b/wallets/metamask/src/pages/OnboardingPage/selectors/index.ts @@ -21,5 +21,5 @@ export default { WalletCreationSuccessPageSelectors, // 5th Page - PinExtensionPageSelectors -} + PinExtensionPageSelectors, +}; diff --git a/wallets/metamask/src/utils/getNotificationPageAndWaitForLoad.ts b/wallets/metamask/src/utils/getNotificationPageAndWaitForLoad.ts index 0f444598c..2a8951782 100644 --- a/wallets/metamask/src/utils/getNotificationPageAndWaitForLoad.ts +++ b/wallets/metamask/src/utils/getNotificationPageAndWaitForLoad.ts @@ -9,7 +9,9 @@ export async function getNotificationPageAndWaitForLoad(context: BrowserContext, let notificationPage = context.pages().find(isNotificationPage) if (!notificationPage) { - notificationPage = await context.waitForEvent('page', { predicate: isNotificationPage }) + notificationPage = await context.waitForEvent('page', { + predicate: isNotificationPage + }) } // Set pop-up window viewport size to resemble the actual MetaMask pop-up window. diff --git a/wallets/metamask/test/e2e/metamask/encrypt.spec.ts b/wallets/metamask/test/e2e/metamask/encrypt.spec.ts new file mode 100644 index 000000000..78981df68 --- /dev/null +++ b/wallets/metamask/test/e2e/metamask/encrypt.spec.ts @@ -0,0 +1,34 @@ +import { testWithMetaMask } from '../testWithMetaMask' + +const test = testWithMetaMask + +const { expect } = test + +test('should provide public encryption key', async ({ page, metamask }) => { + await page.locator('#getEncryptionKeyButton').click() + await metamask.providePublicEncryptionKey() + + await expect(page.locator('#encryptionKeyDisplay')).toHaveText('mtrHp1WHZM9rxF2Ilot9Hie5XmQcKCf7oDQ1DpGkTSI=') +}) + +test('should encrypt and decrypt a message', async ({ page, metamask }) => { + await page.locator('#getEncryptionKeyButton').click() + await metamask.providePublicEncryptionKey() + await expect(page.locator('#encryptionKeyDisplay')).toHaveText('mtrHp1WHZM9rxF2Ilot9Hie5XmQcKCf7oDQ1DpGkTSI=') + + // `fill` does not trigger buttons validation, so we use `type` instead + await page.locator('#encryptMessageInput').type('Hello, world') + + await page.locator('#encryptButton').click() + + const encryptedMessage = await page.locator('#ciphertextDisplay').textContent() + + expect(encryptedMessage).toContain('0x7b') + + await page.locator('#decryptButton').click() + await metamask.decrypt() + + const decryptedMessage = await page.locator('#cleartextDisplay').textContent() + + expect(decryptedMessage).toEqual('Hello, world') +})