From 47ddb321d2cfc14fab8ec8227baa7defd7f3f917 Mon Sep 17 00:00:00 2001 From: MetaMask Bot Date: Wed, 7 Dec 2022 14:06:53 +0000 Subject: [PATCH 01/78] Version v10.24.0 --- CHANGELOG.md | 134 ++++++++++++++++++++++++++++++++++++++++++++++++++- package.json | 2 +- 2 files changed, 134 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0446ee3e4954..da1ac63ae067 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,137 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [10.24.0] +### Uncategorized +- Master sync PR following v10.23.0 ([#16827](https://github.com/MetaMask/metamask-extension/pull/16827)) +- Merge remote-tracking branch 'origin/develop' into master-sync +- Revert "Use new assets contrller package to fix 0 decimal token bug ([#16685](https://github.com/MetaMask/metamask-extension/pull/16685)) +- Revert "Revert "Added "What's New" Notification for Improved token allowance experience ([#16465](https://github.com/MetaMask/metamask-extension/pull/16465)) +- Revert "Revert "Add improved token allowance experience toggle ([#16291](https://github.com/MetaMask/metamask-extension/pull/16291)) +- NFT setApprovalForAll warning popover ([#16195](https://github.com/MetaMask/metamask-extension/pull/16195)) +- `TextField` house keeping 🧹 ([#16668](https://github.com/MetaMask/metamask-extension/pull/16668)) +- `TextFieldBase` house keeping 🧹 ([#16667](https://github.com/MetaMask/metamask-extension/pull/16667)) +- Update qs via yarn.lock to 6.5.3 ([#16823](https://github.com/MetaMask/metamask-extension/pull/16823)) +- Continue converting tests from enzyme to @testing-library/react ([#16753](https://github.com/MetaMask/metamask-extension/pull/16753)) +- Fixed NumericInput Storybook Components (#16734) ([#16734](https://github.com/MetaMask/metamask-extension/pull/16734)) +- Ensure 0% slippage on Arbitrum for wrapping / unwrapping ([#16778](https://github.com/MetaMask/metamask-extension/pull/16778)) +- Upgrade Snow to new version 1.3.0 in MetaMask ([#16815](https://github.com/MetaMask/metamask-extension/pull/16815)) +- Transaction security provider feature flag ([#16776](https://github.com/MetaMask/metamask-extension/pull/16776)) +- Fix getFullTxData so that customTxParamsData is not lost ([#16805](https://github.com/MetaMask/metamask-extension/pull/16805)) +- Updated secondary copy and removed the address component from SetApprovalForAll and NFT Approve screens ([#16292](https://github.com/MetaMask/metamask-extension/pull/16292)) +- Removed Confirm and Cancel events as they are not triggered anymore ([#16777](https://github.com/MetaMask/metamask-extension/pull/16777)) +- remove network name from analytics ([#16781](https://github.com/MetaMask/metamask-extension/pull/16781)) +- Allow adding networks with the same chainId as a preloaded/default network via `wallet_AddEthereumChain` API ([#16733](https://github.com/MetaMask/metamask-extension/pull/16733)) +- Add security & privacy "What's New" message ([#16783](https://github.com/MetaMask/metamask-extension/pull/16783)) +- Bump @metamask/design-tokens from 1.11.0 to 1.11.1 ([#16764](https://github.com/MetaMask/metamask-extension/pull/16764)) +- Network request in background should not start until onboarding is completed ([#16773](https://github.com/MetaMask/metamask-extension/pull/16773)) +- Adding middleware to filter out duplicate requests from DAPP ([#16730](https://github.com/MetaMask/metamask-extension/pull/16730)) +- Updating keyring controller ([#16762](https://github.com/MetaMask/metamask-extension/pull/16762)) +- Add user guidance on signature request screen ([#16600](https://github.com/MetaMask/metamask-extension/pull/16600)) +- TextFieldSearch house keeping updates ([#16669](https://github.com/MetaMask/metamask-extension/pull/16669)) +- Give the user ability to opt out of get balance batch request for all loaded accounts ([#16746](https://github.com/MetaMask/metamask-extension/pull/16746)) +- Feat/16634/buttonicon housekeeping ([#16666](https://github.com/MetaMask/metamask-extension/pull/16666)) +- Feat/16187/text housekeeping ([#16589](https://github.com/MetaMask/metamask-extension/pull/16589)) +- [FLASK] Add snap alerts and prompts via `snap_dialog` RPC method ([#16048](https://github.com/MetaMask/metamask-extension/pull/16048)) +- Use NETWORK_EVENTS.NETWORK_DID_CHANGE to trigger network change callback in assetsContractController ([#16760](https://github.com/MetaMask/metamask-extension/pull/16760)) +- [FLASK] Expose transaction origin to transaction insight snaps ([#16671](https://github.com/MetaMask/metamask-extension/pull/16671)) +- Fix production builds for Flask ([#16757](https://github.com/MetaMask/metamask-extension/pull/16757)) +- Update signature request screens ([#15776](https://github.com/MetaMask/metamask-extension/pull/15776)) +- remove rpc urls from metrics ([#16710](https://github.com/MetaMask/metamask-extension/pull/16710)) +- Add signature request warning modal ([#16225](https://github.com/MetaMask/metamask-extension/pull/16225)) +- Show account name when qr scan in send screen ([#16204](https://github.com/MetaMask/metamask-extension/pull/16204)) +- Fixes 'yarn start' on Windows - LavaPack is not defined (#13318) ([#13318](https://github.com/MetaMask/metamask-extension/pull/13318)) +- Remove fenced code in TypeScript files ([#16742](https://github.com/MetaMask/metamask-extension/pull/16742)) +- [FLASK] Create E2E test for snap management ([#16628](https://github.com/MetaMask/metamask-extension/pull/16628)) +- [FLASK] `snaps-monorepo@0.25.0` ([#16673](https://github.com/MetaMask/metamask-extension/pull/16673)) +- Fix: multiple reject on the signature request screen ([#16199](https://github.com/MetaMask/metamask-extension/pull/16199)) +- Label house keeping updates ([#16680](https://github.com/MetaMask/metamask-extension/pull/16680)) +- HelpText house keeping updates ([#16681](https://github.com/MetaMask/metamask-extension/pull/16681)) +- Update codeowners to reflect importance of review ([#16665](https://github.com/MetaMask/metamask-extension/pull/16665)) +- Use Webpack 5 for Storybook ([#16678](https://github.com/MetaMask/metamask-extension/pull/16678)) +- Not use hardware keyring classes when initializing KeyringController in extension MV3 version ([#16684](https://github.com/MetaMask/metamask-extension/pull/16684)) +- DAPP action replay improvements ([#16250](https://github.com/MetaMask/metamask-extension/pull/16250)) +- fix issue preventing switching to localhost ([#16707](https://github.com/MetaMask/metamask-extension/pull/16707)) +- Continue converting tests from enzyme to @testing-library/react ([#16458](https://github.com/MetaMask/metamask-extension/pull/16458)) +- Restore open api usage fully by snow ([#16722](https://github.com/MetaMask/metamask-extension/pull/16722)) +- Unable to proceed with tx bc of inaccurate/overly aggressive "Insufficient funds for gas" warning #13087 ([#14634](https://github.com/MetaMask/metamask-extension/pull/14634)) +- [e2e] Setup MV3 specific test folder and add 1 simple testcase introducing Service Worker re-start ([#16606](https://github.com/MetaMask/metamask-extension/pull/16606)) +- Token allowance i18n interpolation system ([#16347](https://github.com/MetaMask/metamask-extension/pull/16347)) +- Migrate to new controller packages ([#16547](https://github.com/MetaMask/metamask-extension/pull/16547)) +- Resetting spending cap value to empty when a token allowance request is rejected. ([#16659](https://github.com/MetaMask/metamask-extension/pull/16659)) +- Mitigate flaky test with the use of new function ([#16655](https://github.com/MetaMask/metamask-extension/pull/16655)) +- [e2e] [MV3] Fix Add Account e2e flaky test for MV3 build ([#16603](https://github.com/MetaMask/metamask-extension/pull/16603)) +- Master sync following v10.22.3 ([#16650](https://github.com/MetaMask/metamask-extension/pull/16650)) +- Simplify MV3 initialization ([#16559](https://github.com/MetaMask/metamask-extension/pull/16559)) +- Fix #15050 - MV3: Keep the user logged in when service worker restarts ([#15558](https://github.com/MetaMask/metamask-extension/pull/15558)) +- Integrating snow into metamask ([#15580](https://github.com/MetaMask/metamask-extension/pull/15580)) +- fix infura rpc detection ([#16585](https://github.com/MetaMask/metamask-extension/pull/16585)) +- Remove callback from being saved in controller state ([#16627](https://github.com/MetaMask/metamask-extension/pull/16627)) +- Icon house keeping updates ([#16621](https://github.com/MetaMask/metamask-extension/pull/16621)) +- Fix bundle size diff message ([#16576](https://github.com/MetaMask/metamask-extension/pull/16576)) +- avatar base component housekeeping ([#16583](https://github.com/MetaMask/metamask-extension/pull/16583)) +- Disabled save button on add contact form if input fields are empty ([#16233](https://github.com/MetaMask/metamask-extension/pull/16233)) +- Fix E2E chunking ([#16653](https://github.com/MetaMask/metamask-extension/pull/16653)) +- Fix develop conflicts +- fixed console warning for labelProps ([#16629](https://github.com/MetaMask/metamask-extension/pull/16629)) +- Adding `FormTextField` component ([#16497](https://github.com/MetaMask/metamask-extension/pull/16497)) +- Fix/16620/button href prop ([#16633](https://github.com/MetaMask/metamask-extension/pull/16633)) +- Keep memstore contents after service worker restarts ([#15913](https://github.com/MetaMask/metamask-extension/pull/15913)) +- Adding ITA translations ([#15748](https://github.com/MetaMask/metamask-extension/pull/15748)) +- [FLASK] Clear notification state on restore ([#16503](https://github.com/MetaMask/metamask-extension/pull/16503)) +- [FLASK] Fix a crash that happens after snap install ([#16526](https://github.com/MetaMask/metamask-extension/pull/16526)) +- [FLASK] `snaps-monorepo@0.24.1` ([#16525](https://github.com/MetaMask/metamask-extension/pull/16525)) +- added sm border radius ([#16611](https://github.com/MetaMask/metamask-extension/pull/16611)) +- [e2e] [MV3] Fix Custom RPC e2e test failures for MV3 build ([#16599](https://github.com/MetaMask/metamask-extension/pull/16599)) +- Replace the address in SignTypedData_v4 signatures with a 'Verify contract details' link ([#16191](https://github.com/MetaMask/metamask-extension/pull/16191)) +- Expanded permission_ethereumAccounts spanish translation ([#15660](https://github.com/MetaMask/metamask-extension/pull/15660)) +- Make ENS named elements domain generic ([#16166](https://github.com/MetaMask/metamask-extension/pull/16166)) +- Use async/await for extension functions ([#15722](https://github.com/MetaMask/metamask-extension/pull/15722)) +- BETA - Update to sentence case ([#16590](https://github.com/MetaMask/metamask-extension/pull/16590)) +- Create constants for all keyring types ([#16575](https://github.com/MetaMask/metamask-extension/pull/16575)) +- [FLASK] Improve Snaps E2E stability ([#16597](https://github.com/MetaMask/metamask-extension/pull/16597)) +- updated responsive props for border radius ([#16510](https://github.com/MetaMask/metamask-extension/pull/16510)) +- Feat/16507/button link housekeeping ([#16518](https://github.com/MetaMask/metamask-extension/pull/16518)) +- Updating tokensChainsCache[chainId].data to object from array in user state ([#16535](https://github.com/MetaMask/metamask-extension/pull/16535)) +- updated background color for picker network ([#16466](https://github.com/MetaMask/metamask-extension/pull/16466)) +- Adding static icon names to test env file ([#16078](https://github.com/MetaMask/metamask-extension/pull/16078)) +- Fix message on sign typed data v4 screen ([#16552](https://github.com/MetaMask/metamask-extension/pull/16552)) +- Removing storybook tests ([#16577](https://github.com/MetaMask/metamask-extension/pull/16577)) +- Minor scripts/ui.js file cleanup ([#16566](https://github.com/MetaMask/metamask-extension/pull/16566)) +- Updated Text style in Tag Url ([#16570](https://github.com/MetaMask/metamask-extension/pull/16570)) +- Updating network colors with design tokens ([#16543](https://github.com/MetaMask/metamask-extension/pull/16543)) +- Updating all background-default hovers colors ([#16519](https://github.com/MetaMask/metamask-extension/pull/16519)) +- Ensure prod beta build is created when merging to master ([#16557](https://github.com/MetaMask/metamask-extension/pull/16557)) +- MV3: support Service Worker restart for phishing warning pages ([#16488](https://github.com/MetaMask/metamask-extension/pull/16488)) +- Fix crash on e2e test failure ([#16556](https://github.com/MetaMask/metamask-extension/pull/16556)) +- Add transaction security check toggle ([#16271](https://github.com/MetaMask/metamask-extension/pull/16271)) +- Skip the first token allowance screen if dapp proposing spending cap is 0 ([#16502](https://github.com/MetaMask/metamask-extension/pull/16502)) +- Master sync following v10.22.2 ([#16548](https://github.com/MetaMask/metamask-extension/pull/16548)) +- Merge remote-tracking branch 'origin/develop' into master-sync +- Component library adding global index and other housekeeping ([#16441](https://github.com/MetaMask/metamask-extension/pull/16441)) +- fix(i18n): de lightTheme translation ([#16517](https://github.com/MetaMask/metamask-extension/pull/16517)) +- [FLASK] Update e2e tests for new react test-snaps page ([#16324](https://github.com/MetaMask/metamask-extension/pull/16324)) +- [e2e] Fix RPC flaky test ([#16530](https://github.com/MetaMask/metamask-extension/pull/16530)) +- BETA - Updating welcome message ([#16489](https://github.com/MetaMask/metamask-extension/pull/16489)) +- Bump @metamask/design-tokens from 1.9.0 to 1.11.0 ([#16515](https://github.com/MetaMask/metamask-extension/pull/16515)) +- Add mocks for E2E tests ([#16527](https://github.com/MetaMask/metamask-extension/pull/16527)) +- Modified chain_id value(MetaMetrics), in the Custom Network Added event ([#16426](https://github.com/MetaMask/metamask-extension/pull/16426)) +- Remove unnecessary await ([#16482](https://github.com/MetaMask/metamask-extension/pull/16482)) +- persist user traits for comparison ([#16506](https://github.com/MetaMask/metamask-extension/pull/16506)) +- Configure smart transactions controller to support goerli ([#16500](https://github.com/MetaMask/metamask-extension/pull/16500)) +- button secondary housekeeping ([#16495](https://github.com/MetaMask/metamask-extension/pull/16495)) +- Added "What's New" Notification for Improved token allowance experience ([#16465](https://github.com/MetaMask/metamask-extension/pull/16465)) +- Update `@metamask/controllers` to v33 ([#16493](https://github.com/MetaMask/metamask-extension/pull/16493)) +- Jest: Add browser.runtime (webextension-polyfill) utils tests ([#16483](https://github.com/MetaMask/metamask-extension/pull/16483)) +- Adding some propType fixes to `TextFieldBase` ([#16508](https://github.com/MetaMask/metamask-extension/pull/16508)) +- Adding `TextFieldSearch` component ([#16296](https://github.com/MetaMask/metamask-extension/pull/16296)) +- upgrade gulp-autoprefixer ([#16439](https://github.com/MetaMask/metamask-extension/pull/16439)) +- Feat/16185/button primary housekeeping ([#16457](https://github.com/MetaMask/metamask-extension/pull/16457)) +- added 50% border radius support to the Box component ([#16486](https://github.com/MetaMask/metamask-extension/pull/16486)) +- [i18n:zh_tw] Sync and update translation for zh_TW ([#11212](https://github.com/MetaMask/metamask-extension/pull/11212)) +- Added a 'Verify contract details' link to SetApprovalForAll confirmation screens ([#15756](https://github.com/MetaMask/metamask-extension/pull/15756)) +- MV3: Update service worker restart logic and keep-alive logic for dapp support ([#16075](https://github.com/MetaMask/metamask-extension/pull/16075)) + ## [10.23.0] ### Added - Add Picker Network Component ([#16340](https://github.com/MetaMask/metamask-extension/pull/16340)) @@ -3336,7 +3467,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Uncategorized - Added the ability to restore accounts from seed words. -[Unreleased]: https://github.com/MetaMask/metamask-extension/compare/v10.23.0...HEAD +[Unreleased]: https://github.com/MetaMask/metamask-extension/compare/v10.24.0...HEAD +[10.24.0]: https://github.com/MetaMask/metamask-extension/compare/v10.23.0...v10.24.0 [10.23.0]: https://github.com/MetaMask/metamask-extension/compare/v10.22.3...v10.23.0 [10.22.3]: https://github.com/MetaMask/metamask-extension/compare/v10.22.2...v10.22.3 [10.22.2]: https://github.com/MetaMask/metamask-extension/compare/v10.22.1...v10.22.2 diff --git a/package.json b/package.json index 7c1bf4fb68bd..313b79874bc9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "metamask-crx", - "version": "10.23.0", + "version": "10.24.0", "private": true, "repository": { "type": "git", From 5f6d5706eff69436f76244b0de7277fc00b057f1 Mon Sep 17 00:00:00 2001 From: Pedro Figueiredo Date: Thu, 8 Dec 2022 14:20:59 +0000 Subject: [PATCH 02/78] fix locales for advance config (#16849) --- app/_locales/de/messages.json | 3 --- app/_locales/el/messages.json | 3 --- app/_locales/en/messages.json | 6 +++--- app/_locales/es/messages.json | 3 --- app/_locales/es_419/messages.json | 3 --- app/_locales/fr/messages.json | 3 --- app/_locales/hi/messages.json | 3 --- app/_locales/id/messages.json | 3 --- app/_locales/ja/messages.json | 3 --- app/_locales/ko/messages.json | 3 --- app/_locales/pt/messages.json | 3 --- app/_locales/pt_BR/messages.json | 3 --- app/_locales/ru/messages.json | 3 --- app/_locales/tl/messages.json | 3 --- app/_locales/tr/messages.json | 3 --- app/_locales/vi/messages.json | 3 --- app/_locales/zh_CN/messages.json | 3 --- .../creation-successful/creation-successful.js | 2 +- .../creation-successful/creation-successful.test.js | 4 ++-- .../onboarding-flow/privacy-settings/privacy-settings.js | 2 +- 20 files changed, 7 insertions(+), 55 deletions(-) diff --git a/app/_locales/de/messages.json b/app/_locales/de/messages.json index 44bb787c39dc..1214b7d31c8a 100644 --- a/app/_locales/de/messages.json +++ b/app/_locales/de/messages.json @@ -3055,9 +3055,6 @@ "sepolia": { "message": "Sepolia-Testnetzwerk" }, - "setAdvancedPrivacySettings": { - "message": "Erweiterte Privatsphäre-Einstellungen festlegen" - }, "setAdvancedPrivacySettingsDetails": { "message": "MetaMask nutzt diese vertrauenswürdigen Dienstleistungen von Drittanbietern, um die Benutzerfreundlichkeit und Sicherheit der Produkte zu verbessern." }, diff --git a/app/_locales/el/messages.json b/app/_locales/el/messages.json index c8c54e3060d4..fb934fbb2156 100644 --- a/app/_locales/el/messages.json +++ b/app/_locales/el/messages.json @@ -3055,9 +3055,6 @@ "sepolia": { "message": "Δίκτυο δοκιμών Sepolia" }, - "setAdvancedPrivacySettings": { - "message": "Ορίστε ρυθμίσεις απορρήτου για προχωρημένους" - }, "setAdvancedPrivacySettingsDetails": { "message": "Το MetaMask χρησιμοποιεί αυτές τις αξιόπιστες υπηρεσίες τρίτων για να ενισχύσει τη χρηστικότητα και την ασφάλεια των προϊόντων." }, diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index 97067ee23146..99a590f365c2 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -266,6 +266,9 @@ "advancedBaseGasFeeToolTip": { "message": "When your transaction gets included in the block, any difference between your max base fee and the actual base fee will be refunded. Total amount is calculated as max base fee (in GWEI) * gas limit." }, + "advancedConfiguration": { + "message": "Advanced configuration" + }, "advancedGasFeeDefaultOptIn": { "message": "Save these $1 as my default for \"Advanced\"" }, @@ -3249,9 +3252,6 @@ "sepolia": { "message": "Sepolia test network" }, - "setAdvancedPrivacySettings": { - "message": "Set advanced privacy settings" - }, "setAdvancedPrivacySettingsDetails": { "message": "MetaMask uses these trusted third-party services to enhance product usability and safety." }, diff --git a/app/_locales/es/messages.json b/app/_locales/es/messages.json index 4abbc36a57c4..f24bc63cf2f4 100644 --- a/app/_locales/es/messages.json +++ b/app/_locales/es/messages.json @@ -3055,9 +3055,6 @@ "sepolia": { "message": "Red de prueba Sepolia" }, - "setAdvancedPrivacySettings": { - "message": "Configuración avanzada de privacidad" - }, "setAdvancedPrivacySettingsDetails": { "message": "MetaMask utiliza estos servicios de terceros de confianza para mejorar la usabilidad y la seguridad de los productos." }, diff --git a/app/_locales/es_419/messages.json b/app/_locales/es_419/messages.json index 06e1ed52c0c4..a1fb4c753450 100644 --- a/app/_locales/es_419/messages.json +++ b/app/_locales/es_419/messages.json @@ -2358,9 +2358,6 @@ "message": "Enviando $1", "description": "$1 represents the native currency symbol for the current network (e.g. ETH or BNB)" }, - "setAdvancedPrivacySettings": { - "message": "Configuración avanzada de privacidad" - }, "setAdvancedPrivacySettingsDetails": { "message": "MetaMask utiliza estos servicios de terceros de confianza para mejorar la usabilidad y la seguridad de los productos." }, diff --git a/app/_locales/fr/messages.json b/app/_locales/fr/messages.json index c9dfc3d15691..1aa2cb1c427d 100644 --- a/app/_locales/fr/messages.json +++ b/app/_locales/fr/messages.json @@ -3055,9 +3055,6 @@ "sepolia": { "message": "Réseau de test Sepolia" }, - "setAdvancedPrivacySettings": { - "message": "Définir des paramètres de confidentialité avancés" - }, "setAdvancedPrivacySettingsDetails": { "message": "MetaMask utilise ces services tiers de confiance pour améliorer la convivialité et la sécurité des produits." }, diff --git a/app/_locales/hi/messages.json b/app/_locales/hi/messages.json index f8b4b3d8bcdf..80e14bd5eb1e 100644 --- a/app/_locales/hi/messages.json +++ b/app/_locales/hi/messages.json @@ -3055,9 +3055,6 @@ "sepolia": { "message": "सेपोलिया टेस्ट नेटवर्क" }, - "setAdvancedPrivacySettings": { - "message": "एडवांस गोपनीयता सेटिंग्स निर्धारित करें" - }, "setAdvancedPrivacySettingsDetails": { "message": "MetaMask उत्पाद की उपयोगिता और सुरक्षा को बढ़ाने के लिए इन विश्वसनीय तीसरे-पक्ष की सेवाओं का उपयोग करता है।" }, diff --git a/app/_locales/id/messages.json b/app/_locales/id/messages.json index 952c13746e66..bd6b83be7642 100644 --- a/app/_locales/id/messages.json +++ b/app/_locales/id/messages.json @@ -3055,9 +3055,6 @@ "sepolia": { "message": "Jaringan uji Sepolia" }, - "setAdvancedPrivacySettings": { - "message": "Atur pengaturan privasi lanjutan" - }, "setAdvancedPrivacySettingsDetails": { "message": "MetaMask menggunakan layanan pihak ketiga tepercaya ini untuk meningkatkan kegunaan dan keamanan produk." }, diff --git a/app/_locales/ja/messages.json b/app/_locales/ja/messages.json index 9d4c21e19fc6..d75f554274f6 100644 --- a/app/_locales/ja/messages.json +++ b/app/_locales/ja/messages.json @@ -3055,9 +3055,6 @@ "sepolia": { "message": "Sepolia テストネットワーク" }, - "setAdvancedPrivacySettings": { - "message": "高度なプライバシー設定を設定" - }, "setAdvancedPrivacySettingsDetails": { "message": "MetaMaskはこれらの信頼できるサードパーティーサービスを使用して、製品の使いやすさと安全性を向上させています。" }, diff --git a/app/_locales/ko/messages.json b/app/_locales/ko/messages.json index 0b90d9a73de2..eb1059d64d15 100644 --- a/app/_locales/ko/messages.json +++ b/app/_locales/ko/messages.json @@ -3055,9 +3055,6 @@ "sepolia": { "message": "Sepolia 테스트 네트워크" }, - "setAdvancedPrivacySettings": { - "message": "개인정보 설정 고급 지정" - }, "setAdvancedPrivacySettingsDetails": { "message": "이와 같이 MetaMask는 신용있는 타사의 서비스를 사용하여 제품 가용성과 안전성을 향상합니다." }, diff --git a/app/_locales/pt/messages.json b/app/_locales/pt/messages.json index 340b32b822a8..e9f3450c59ef 100644 --- a/app/_locales/pt/messages.json +++ b/app/_locales/pt/messages.json @@ -3055,9 +3055,6 @@ "sepolia": { "message": "Rede de teste Sepolia" }, - "setAdvancedPrivacySettings": { - "message": "Definir configurações avançadas de privacidade" - }, "setAdvancedPrivacySettingsDetails": { "message": "A MetaMask utiliza esses serviços terceirizados de confiança para aumentar a usabilidade e a segurança dos produtos." }, diff --git a/app/_locales/pt_BR/messages.json b/app/_locales/pt_BR/messages.json index decaf2f96797..186e4b10d1c8 100644 --- a/app/_locales/pt_BR/messages.json +++ b/app/_locales/pt_BR/messages.json @@ -2342,9 +2342,6 @@ "message": "Enviando $1", "description": "$1 represents the native currency symbol for the current network (e.g. ETH or BNB)" }, - "setAdvancedPrivacySettings": { - "message": "Definir configurações avançadas de privacidade" - }, "setAdvancedPrivacySettingsDetails": { "message": "A MetaMask utiliza esses serviços terceirizados de confiança para aumentar a usabilidade e a segurança dos produtos." }, diff --git a/app/_locales/ru/messages.json b/app/_locales/ru/messages.json index 4cf73155acd0..ab78a812d886 100644 --- a/app/_locales/ru/messages.json +++ b/app/_locales/ru/messages.json @@ -3055,9 +3055,6 @@ "sepolia": { "message": "Тестовая сеть Sepolia" }, - "setAdvancedPrivacySettings": { - "message": "Задать дополнительные настройки конфиденциальности" - }, "setAdvancedPrivacySettingsDetails": { "message": "MetaMask использует эти доверенные сторонние сервисы для повышения удобства использования и безопасности продукта." }, diff --git a/app/_locales/tl/messages.json b/app/_locales/tl/messages.json index 51d1688db1eb..af04e52756e7 100644 --- a/app/_locales/tl/messages.json +++ b/app/_locales/tl/messages.json @@ -3055,9 +3055,6 @@ "sepolia": { "message": "Sepolia test network" }, - "setAdvancedPrivacySettings": { - "message": "Magtakda ng advanced privacy settings" - }, "setAdvancedPrivacySettingsDetails": { "message": "Ginagamit ng MetaMask ang mga pinagkakatiwalaang serbisyo ng third-party na ito para mapahusay ang kakayahang magamit at kaligtasan ng produkto." }, diff --git a/app/_locales/tr/messages.json b/app/_locales/tr/messages.json index e8ce06e76992..8f01179a986f 100644 --- a/app/_locales/tr/messages.json +++ b/app/_locales/tr/messages.json @@ -3055,9 +3055,6 @@ "sepolia": { "message": "Sepolia test ağı" }, - "setAdvancedPrivacySettings": { - "message": "Gelişmiş gizlilik ayarlarını yapın" - }, "setAdvancedPrivacySettingsDetails": { "message": "MetaMask, ürünün kullanılabilirliğini ve güvenliğini iyileştirmek amacıyla bu güvenilir üçüncü taraf hizmetlerini kullanır." }, diff --git a/app/_locales/vi/messages.json b/app/_locales/vi/messages.json index 8d6e6a023003..4f87dcbf5051 100644 --- a/app/_locales/vi/messages.json +++ b/app/_locales/vi/messages.json @@ -3055,9 +3055,6 @@ "sepolia": { "message": "Mạng thử nghiệm Sepolia" }, - "setAdvancedPrivacySettings": { - "message": "Thiết lập cài đặt quyền riêng tư nâng cao" - }, "setAdvancedPrivacySettingsDetails": { "message": "MetaMask sử dụng các dịch vụ của bên thứ ba đáng tin cậy này để nâng cao sự hữu ích và an toàn của sản phẩm." }, diff --git a/app/_locales/zh_CN/messages.json b/app/_locales/zh_CN/messages.json index 541ba0db913c..efffd5857563 100644 --- a/app/_locales/zh_CN/messages.json +++ b/app/_locales/zh_CN/messages.json @@ -3055,9 +3055,6 @@ "sepolia": { "message": "Sepolia测试网络" }, - "setAdvancedPrivacySettings": { - "message": "设置高级隐私设置" - }, "setAdvancedPrivacySettingsDetails": { "message": "MetaMask 使用这些可信的第三方服务来提高产品可用性和安全性。" }, diff --git a/ui/pages/onboarding-flow/creation-successful/creation-successful.js b/ui/pages/onboarding-flow/creation-successful/creation-successful.js index 356fd89b5577..0cbf7bdd27cc 100644 --- a/ui/pages/onboarding-flow/creation-successful/creation-successful.js +++ b/ui/pages/onboarding-flow/creation-successful/creation-successful.js @@ -93,7 +93,7 @@ export default function CreationSuccessful() { type="link" onClick={() => history.push(ONBOARDING_PRIVACY_SETTINGS_ROUTE)} > - {t('setAdvancedPrivacySettings')} + {t('advancedConfiguration')} + From 9dbc8b8ec0b269d1d0466072a0fd41b720c5ec61 Mon Sep 17 00:00:00 2001 From: David Walsh Date: Thu, 8 Dec 2022 10:42:23 -0600 Subject: [PATCH 04/78] Privacy - Show default selected network after a custom network has been added during onboarding (#16789) * Privacy - Allow users to set a custom RPC from the onboarding process (#16767) * Privacy - Allow adding custom IPFS from onboarding (#16782) * Privacy - Show default selected network after a custom network has been added during onboarding * WIP: Show dropdown list of networks * Add network switcher to the onboarding advanced privacy screen * Fix duplicate imports * Provide default for networks * Update ui/helpers/utils/ipfs.js Co-authored-by: legobeat <109787230+legobeat@users.noreply.github.com> * Fix lint * Remove unwanted changes * Fix lint Co-authored-by: legobeat <109787230+legobeat@users.noreply.github.com> --- app/_locales/en/messages.json | 24 ++++ .../app/dropdowns/network-dropdown.js | 43 ++++-- ui/components/app/modals/modal.js | 5 + ui/helpers/utils/ipfs.js | 3 + .../add-network-modal/index.js | 43 ++++++ .../privacy-settings/index.scss | 9 ++ .../privacy-settings/privacy-settings.js | 125 +++++++++++++++++- .../privacy-settings/privacy-settings.test.js | 1 + .../privacy-settings/setting.js | 17 ++- ui/pages/routes/routes.component.js | 5 +- ui/pages/routes/routes.container.js | 2 + .../advanced-tab/advanced-tab.component.js | 8 +- .../networks-form/networks-form.js | 15 +-- .../networks-tab-content.js | 9 ++ .../settings/networks-tab/networks-tab.js | 4 + 15 files changed, 278 insertions(+), 35 deletions(-) create mode 100644 ui/helpers/utils/ipfs.js create mode 100644 ui/pages/onboarding-flow/add-network-modal/index.js diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index 663ab0d5e0ff..e5515c752e91 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -2586,6 +2586,27 @@ "on": { "message": "On" }, + "onboardingAdvancedPrivacyIPFSDescription": { + "message": "The IPFS gateway makes it possible to access and view data hosted by third parties. You can add a custom IPFS gateway or continue using the default." + }, + "onboardingAdvancedPrivacyIPFSInvalid": { + "message": "Please enter a valid URL" + }, + "onboardingAdvancedPrivacyIPFSTitle": { + "message": "Add custom IPFS Gateway" + }, + "onboardingAdvancedPrivacyIPFSValid": { + "message": "IPFS gateway URL is valid" + }, + "onboardingAdvancedPrivacyNetworkButton": { + "message": "Add custom network" + }, + "onboardingAdvancedPrivacyNetworkDescription": { + "message": "We use Infura as our remote procedure call (RPC) provider to offer the most reliable and private access to Ethereum data we can. You can choose your own RPC, but remember that any RPC will receive your IP address and Ethereum wallet to make transactions. Read our $1 to learn more about how Infura handles data." + }, + "onboardingAdvancedPrivacyNetworkTitle": { + "message": "Choose your network" + }, "onboardingCreateWallet": { "message": "Create a new wallet" }, @@ -2620,6 +2641,9 @@ "onboardingMetametricsInfuraTermsPolicyLink": { "message": "here" }, + "onboardingMetametricsModalTitle": { + "message": "Add custom network" + }, "onboardingMetametricsNeverCollect": { "message": "$1 collect information we don’t need to provide the service (such as keys, addresses, transaction hashes, or balances)", "description": "$1 represents `onboardingMetametricsNeverEmphasis`" diff --git a/ui/components/app/dropdowns/network-dropdown.js b/ui/components/app/dropdowns/network-dropdown.js index e231251112e5..3badd8c078e1 100644 --- a/ui/components/app/dropdowns/network-dropdown.js +++ b/ui/components/app/dropdowns/network-dropdown.js @@ -101,6 +101,9 @@ class NetworkDropdown extends Component { showTestnetMessageInDropdown: PropTypes.bool.isRequired, hideTestNetMessage: PropTypes.func.isRequired, history: PropTypes.object, + dropdownStyles: PropTypes.object, + hideElementsForOnboarding: PropTypes.bool, + onAddClick: PropTypes.func, }; handleClick(newProviderType) { @@ -122,16 +125,21 @@ class NetworkDropdown extends Component { } renderAddCustomButton() { + const { onAddClick } = this.props; return (
+ ) : null} + + + } + /> + + {t('onboardingAdvancedPrivacyIPFSDescription')} + + { + handleIPFSChange(e.target.value); + }} + /> + {ipfsURL ? ( + + {ipfsError || t('onboardingAdvancedPrivacyIPFSValid')} + + ) : null} + + + } + />
+ )} + {showContractDetails && ( Date: Wed, 14 Dec 2022 11:48:50 +0100 Subject: [PATCH 06/78] [FLASK] Bump snaps `iframe-execution-environment` (#16932) --- app/scripts/metamask-controller.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 6a7dd7eb7e0c..1f6444237f99 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -686,7 +686,7 @@ export default class MetamaskController extends EventEmitter { ///: BEGIN:ONLY_INCLUDE_IN(flask) this.snapExecutionService = new IframeExecutionService({ iframeUrl: new URL( - 'https://metamask.github.io/iframe-execution-environment/0.11.0', + 'https://metamask.github.io/iframe-execution-environment/0.11.1', ), messenger: this.controllerMessenger.getRestricted({ name: 'ExecutionService', From 8d8fcdcf0ed606f3449e8711ddeaa425ba65860f Mon Sep 17 00:00:00 2001 From: Jyoti Puri Date: Wed, 14 Dec 2022 02:53:39 +0530 Subject: [PATCH 07/78] ButtonIcon: fix react component proptype (#16942) --- ui/components/component-library/button-icon/button-icon.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/components/component-library/button-icon/button-icon.js b/ui/components/component-library/button-icon/button-icon.js index 580c66729068..79c4ccb05b73 100644 --- a/ui/components/component-library/button-icon/button-icon.js +++ b/ui/components/component-library/button-icon/button-icon.js @@ -85,7 +85,7 @@ ButtonIcon.propTypes = { /** * The name of the icon to display. Should be one of ICON_NAMES */ - iconName: PropTypes.oneOf(ICON_NAMES).isRequired, + iconName: PropTypes.oneOf(Object.values(ICON_NAMES)).isRequired, /** * iconProps accepts all the props from Icon */ From fde7cb5e17b902faa8f0138e6ab46f687607423e Mon Sep 17 00:00:00 2001 From: Alex Donesky Date: Tue, 13 Dec 2022 12:08:28 -0600 Subject: [PATCH 08/78] remove the ability to navigate back into the onboarding flow after completing onboarding (#16916) * fix issue when navigating back into the onboarding flow after completing onboarding * disable navigating back into the onboarding flow * lint * fix test * lint --- ui/pages/home/home.component.js | 10 ++++--- ui/pages/onboarding-flow/onboarding-flow.js | 30 ++++++++++++------- .../onboarding-flow/onboarding-flow.test.js | 1 + 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/ui/pages/home/home.component.js b/ui/pages/home/home.component.js index 718c5174f2b7..83af69b674eb 100644 --- a/ui/pages/home/home.component.js +++ b/ui/pages/home/home.component.js @@ -45,6 +45,7 @@ import { VIEW_QUOTE_ROUTE, CONFIRMATION_V_NEXT_ROUTE, ADD_COLLECTIBLE_ROUTE, + ONBOARDING_SECURE_YOUR_WALLET_ROUTE, } from '../../helpers/constants/routes'; import ZENDESK_URLS from '../../helpers/constants/zendesk-url'; import Tooltip from '../../components/ui/tooltip'; @@ -414,12 +415,13 @@ export default class Home extends PureComponent { descriptionText={t('backupApprovalNotice')} acceptText={t('backupNow')} onAccept={() => { + const backUpSRPRoute = process.env.ONBOARDING_V2 + ? `${ONBOARDING_SECURE_YOUR_WALLET_ROUTE}/?isFromReminder=true` + : INITIALIZE_BACKUP_SEED_PHRASE_ROUTE; if (isPopup) { - global.platform.openExtensionInBrowser( - INITIALIZE_BACKUP_SEED_PHRASE_ROUTE, - ); + global.platform.openExtensionInBrowser(backUpSRPRoute); } else { - history.push(INITIALIZE_BACKUP_SEED_PHRASE_ROUTE); + history.push(backUpSRPRoute); } }} infoText={t('backupApprovalInfo')} diff --git a/ui/pages/onboarding-flow/onboarding-flow.js b/ui/pages/onboarding-flow/onboarding-flow.js index 8a3be4e289e8..6dcc43ee1bfa 100644 --- a/ui/pages/onboarding-flow/onboarding-flow.js +++ b/ui/pages/onboarding-flow/onboarding-flow.js @@ -19,14 +19,12 @@ import { ONBOARDING_PIN_EXTENSION_ROUTE, ONBOARDING_METAMETRICS, } from '../../helpers/constants/routes'; -import { - getCompletedOnboarding, - getSeedPhraseBackedUp, -} from '../../ducks/metamask/metamask'; +import { getCompletedOnboarding } from '../../ducks/metamask/metamask'; import { createNewVaultAndGetSeedPhrase, unlockAndGetSeedPhrase, createNewVaultAndRestore, + verifySeedPhrase, } from '../../store/actions'; import { getFirstTimeFlowTypeRoute } from '../../selectors'; import Button from '../../components/ui/button'; @@ -49,18 +47,29 @@ import MetaMetricsComponent from './metametrics/metametrics'; export default function OnboardingFlow() { const [secretRecoveryPhrase, setSecretRecoveryPhrase] = useState(''); const dispatch = useDispatch(); - const currentLocation = useLocation(); + const { pathName, search } = useLocation(); const history = useHistory(); const t = useI18nContext(); const completedOnboarding = useSelector(getCompletedOnboarding); - const seedPhraseBackedUp = useSelector(getSeedPhraseBackedUp); const nextRoute = useSelector(getFirstTimeFlowTypeRoute); - + const isFromReminder = new URLSearchParams(search).get('isFromReminder'); useEffect(() => { - if (completedOnboarding && seedPhraseBackedUp) { + if (completedOnboarding && !isFromReminder) { history.push(DEFAULT_ROUTE); } - }, [history, completedOnboarding, seedPhraseBackedUp]); + }, [history, completedOnboarding, isFromReminder]); + + useEffect(() => { + const verifyAndSetSeedPhrase = async () => { + if (completedOnboarding && !secretRecoveryPhrase) { + const verifiedSeedPhrase = await verifySeedPhrase(); + if (verifiedSeedPhrase) { + setSecretRecoveryPhrase(verifiedSeedPhrase); + } + } + }; + verifyAndSetSeedPhrase(); + }, [completedOnboarding, secretRecoveryPhrase]); const handleCreateNewAccount = async (password) => { const newSecretRecoveryPhrase = await dispatch( @@ -97,7 +106,6 @@ export default function OnboardingFlow() { )} /> @@ -170,7 +178,7 @@ export default function OnboardingFlow() { - {currentLocation?.pathname === ONBOARDING_COMPLETION_ROUTE && ( + {pathName === ONBOARDING_COMPLETION_ROUTE && ( + + { + e.preventDefault(); + setShowPassword(!showPassword); + }} + > + {showPassword ? t('hide') : t('show')} + + } /> Date: Wed, 14 Dec 2022 00:49:52 -0600 Subject: [PATCH 13/78] fix issue where final onboarding pages are not show (#16943) --- .../creation-successful.js | 9 +--- .../creation-successful.test.js | 7 --- .../pin-extension/pin-extension.js | 21 +++++---- .../pin-extension/pin-extension.test.js | 43 +++++++++++++++++++ 4 files changed, 57 insertions(+), 23 deletions(-) create mode 100644 ui/pages/onboarding-flow/pin-extension/pin-extension.test.js diff --git a/ui/pages/onboarding-flow/creation-successful/creation-successful.js b/ui/pages/onboarding-flow/creation-successful/creation-successful.js index 0cbf7bdd27cc..9f33dbfa2524 100644 --- a/ui/pages/onboarding-flow/creation-successful/creation-successful.js +++ b/ui/pages/onboarding-flow/creation-successful/creation-successful.js @@ -1,6 +1,5 @@ import React from 'react'; import { useHistory } from 'react-router-dom'; -import { useDispatch } from 'react-redux'; import Box from '../../../components/ui/box'; import Typography from '../../../components/ui/typography'; @@ -16,18 +15,12 @@ import { ONBOARDING_PIN_EXTENSION_ROUTE, ONBOARDING_PRIVACY_SETTINGS_ROUTE, } from '../../../helpers/constants/routes'; -import { setCompletedOnboarding } from '../../../store/actions'; import { isBeta } from '../../../helpers/utils/build-types'; export default function CreationSuccessful() { const history = useHistory(); const t = useI18nContext(); - const dispatch = useDispatch(); - const onComplete = async () => { - await dispatch(setCompletedOnboarding()); - history.push(ONBOARDING_PIN_EXTENSION_ROUTE); - }; return (
@@ -100,7 +93,7 @@ export default function CreationSuccessful() { type="primary" large rounded - onClick={onComplete} + onClick={() => history.push(ONBOARDING_PIN_EXTENSION_ROUTE)} > {t('gotIt')} diff --git a/ui/pages/onboarding-flow/creation-successful/creation-successful.test.js b/ui/pages/onboarding-flow/creation-successful/creation-successful.test.js index 4b0d57125362..81581d779884 100644 --- a/ui/pages/onboarding-flow/creation-successful/creation-successful.test.js +++ b/ui/pages/onboarding-flow/creation-successful/creation-successful.test.js @@ -33,13 +33,6 @@ describe('Creation Successful Onboarding View', () => { .mockReturnValue({ push: pushMock }); }); - it('should call completeOnboarding in the background when "Got it!" button is clicked', () => { - const { getByText } = renderWithProvider(, store); - const gotItButton = getByText('Got it!'); - fireEvent.click(gotItButton); - expect(completeOnboardingStub).toHaveBeenCalledTimes(1); - }); - it('should redirect to privacy-settings view when "Advanced configuration" button is clicked', () => { const { getByText } = renderWithProvider(, store); const privacySettingsButton = getByText('Advanced configuration'); diff --git a/ui/pages/onboarding-flow/pin-extension/pin-extension.js b/ui/pages/onboarding-flow/pin-extension/pin-extension.js index 3fbfd94b391d..674df0280e56 100644 --- a/ui/pages/onboarding-flow/pin-extension/pin-extension.js +++ b/ui/pages/onboarding-flow/pin-extension/pin-extension.js @@ -1,6 +1,6 @@ import React, { useState } from 'react'; import { useHistory } from 'react-router-dom'; - +import { useDispatch } from 'react-redux'; import { Carousel } from 'react-responsive-carousel'; import Typography from '../../../components/ui/typography/typography'; import { useI18nContext } from '../../../hooks/useI18nContext'; @@ -11,12 +11,23 @@ import { TEXT_ALIGN, } from '../../../helpers/constants/design-system'; import { DEFAULT_ROUTE } from '../../../helpers/constants/routes'; +import { setCompletedOnboarding } from '../../../store/actions'; import OnboardingPinBillboard from './pin-billboard'; export default function OnboardingPinExtension() { const t = useI18nContext(); const [selectedIndex, setSelectedIndex] = useState(0); const history = useHistory(); + const dispatch = useDispatch(); + + const handleClick = async () => { + if (selectedIndex === 0) { + setSelectedIndex(1); + } else { + await dispatch(setCompletedOnboarding()); + history.push(DEFAULT_ROUTE); + } + }; return (
{ - if (selectedIndex === 0) { - setSelectedIndex(1); - } else { - history.push(DEFAULT_ROUTE); - } - }} + onClick={handleClick} > {selectedIndex === 0 ? t('next') : t('done')} diff --git a/ui/pages/onboarding-flow/pin-extension/pin-extension.test.js b/ui/pages/onboarding-flow/pin-extension/pin-extension.test.js new file mode 100644 index 000000000000..c3a4d70d948b --- /dev/null +++ b/ui/pages/onboarding-flow/pin-extension/pin-extension.test.js @@ -0,0 +1,43 @@ +import React from 'react'; +import { fireEvent } from '@testing-library/react'; +import reactRouterDom from 'react-router-dom'; +import configureMockStore from 'redux-mock-store'; +import thunk from 'redux-thunk'; +import { + renderWithProvider, + setBackgroundConnection, +} from '../../../../test/jest'; +import PinExtension from './pin-extension'; + +const completeOnboardingStub = jest + .fn() + .mockImplementation(() => Promise.resolve()); + +describe('Creation Successful Onboarding View', () => { + const mockStore = { + metamask: { + provider: { + type: 'test', + }, + }, + }; + const store = configureMockStore([thunk])(mockStore); + setBackgroundConnection({ completeOnboarding: completeOnboardingStub }); + + const pushMock = jest.fn(); + beforeAll(() => { + jest + .spyOn(reactRouterDom, 'useHistory') + .mockImplementation() + .mockReturnValue({ push: pushMock }); + }); + + it('should call completeOnboarding in the background when Done" button is clicked', () => { + const { getByText } = renderWithProvider(, store); + const nextButton = getByText('Next'); + fireEvent.click(nextButton); + const gotItButton = getByText('Done'); + fireEvent.click(gotItButton); + expect(completeOnboardingStub).toHaveBeenCalledTimes(1); + }); +}); From 3859c25cac6963d306bb7bd2c0435132da405cf5 Mon Sep 17 00:00:00 2001 From: seaona <54408225+seaona@users.noreply.github.com> Date: Thu, 15 Dec 2022 09:49:54 +0100 Subject: [PATCH 14/78] Changelog for 10.24.0 (#16888) * Changelog for 10.24.0 * Update FLASK snaps-monorepo entry Co-authored-by: Frederik Bolding * Flask entries Co-authored-by: Frederik Bolding * Small fixes on changelog entries * Updated Flask entries classification * Add new cherry-picked entries * Small fix for reject tx entry * Update CHANGELOG.md [FLASK] Fix usage of wrong `ethereum` global for `ethereum` endowment Co-authored-by: Frederik Bolding Co-authored-by: Frederik Bolding --- CHANGELOG.md | 177 +++++++++++++++------------------------------------ 1 file changed, 53 insertions(+), 124 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index da1ac63ae067..04d3fcfd5969 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,135 +7,64 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ## [10.24.0] -### Uncategorized -- Master sync PR following v10.23.0 ([#16827](https://github.com/MetaMask/metamask-extension/pull/16827)) -- Merge remote-tracking branch 'origin/develop' into master-sync -- Revert "Use new assets contrller package to fix 0 decimal token bug ([#16685](https://github.com/MetaMask/metamask-extension/pull/16685)) -- Revert "Revert "Added "What's New" Notification for Improved token allowance experience ([#16465](https://github.com/MetaMask/metamask-extension/pull/16465)) -- Revert "Revert "Add improved token allowance experience toggle ([#16291](https://github.com/MetaMask/metamask-extension/pull/16291)) -- NFT setApprovalForAll warning popover ([#16195](https://github.com/MetaMask/metamask-extension/pull/16195)) -- `TextField` house keeping 🧹 ([#16668](https://github.com/MetaMask/metamask-extension/pull/16668)) -- `TextFieldBase` house keeping 🧹 ([#16667](https://github.com/MetaMask/metamask-extension/pull/16667)) -- Update qs via yarn.lock to 6.5.3 ([#16823](https://github.com/MetaMask/metamask-extension/pull/16823)) -- Continue converting tests from enzyme to @testing-library/react ([#16753](https://github.com/MetaMask/metamask-extension/pull/16753)) -- Fixed NumericInput Storybook Components (#16734) ([#16734](https://github.com/MetaMask/metamask-extension/pull/16734)) -- Ensure 0% slippage on Arbitrum for wrapping / unwrapping ([#16778](https://github.com/MetaMask/metamask-extension/pull/16778)) -- Upgrade Snow to new version 1.3.0 in MetaMask ([#16815](https://github.com/MetaMask/metamask-extension/pull/16815)) -- Transaction security provider feature flag ([#16776](https://github.com/MetaMask/metamask-extension/pull/16776)) -- Fix getFullTxData so that customTxParamsData is not lost ([#16805](https://github.com/MetaMask/metamask-extension/pull/16805)) -- Updated secondary copy and removed the address component from SetApprovalForAll and NFT Approve screens ([#16292](https://github.com/MetaMask/metamask-extension/pull/16292)) -- Removed Confirm and Cancel events as they are not triggered anymore ([#16777](https://github.com/MetaMask/metamask-extension/pull/16777)) -- remove network name from analytics ([#16781](https://github.com/MetaMask/metamask-extension/pull/16781)) -- Allow adding networks with the same chainId as a preloaded/default network via `wallet_AddEthereumChain` API ([#16733](https://github.com/MetaMask/metamask-extension/pull/16733)) -- Add security & privacy "What's New" message ([#16783](https://github.com/MetaMask/metamask-extension/pull/16783)) -- Bump @metamask/design-tokens from 1.11.0 to 1.11.1 ([#16764](https://github.com/MetaMask/metamask-extension/pull/16764)) -- Network request in background should not start until onboarding is completed ([#16773](https://github.com/MetaMask/metamask-extension/pull/16773)) -- Adding middleware to filter out duplicate requests from DAPP ([#16730](https://github.com/MetaMask/metamask-extension/pull/16730)) -- Updating keyring controller ([#16762](https://github.com/MetaMask/metamask-extension/pull/16762)) -- Add user guidance on signature request screen ([#16600](https://github.com/MetaMask/metamask-extension/pull/16600)) -- TextFieldSearch house keeping updates ([#16669](https://github.com/MetaMask/metamask-extension/pull/16669)) -- Give the user ability to opt out of get balance batch request for all loaded accounts ([#16746](https://github.com/MetaMask/metamask-extension/pull/16746)) -- Feat/16634/buttonicon housekeeping ([#16666](https://github.com/MetaMask/metamask-extension/pull/16666)) -- Feat/16187/text housekeeping ([#16589](https://github.com/MetaMask/metamask-extension/pull/16589)) +### Added +- Add NFT setApprovalForAll warning popover when approving the NFT Colleciton ([#16195](https://github.com/MetaMask/metamask-extension/pull/16195)) +- Add "What's New" notification for Security & Privacy ([#16783](https://github.com/MetaMask/metamask-extension/pull/16783)) +- Add informational message on Signature request screen as a user guidance ([#16600](https://github.com/MetaMask/metamask-extension/pull/16600)) +- Add ability to opt out from getting balances as a batch request for all loaded accounts ([#16746](https://github.com/MetaMask/metamask-extension/pull/16746)) +- Add Signature request warning modal ([#16225](https://github.com/MetaMask/metamask-extension/pull/16225)) +- Add Improved Token Allowance experience toggle under Experimental Settings ([#16291](https://github.com/MetaMask/metamask-extension/pull/16291)) +- Add "What's New" Notification for Improved token Allowance Experience ([#16465](https://github.com/MetaMask/metamask-extension/pull/16465)) +- Add new IT translations ([#15748](https://github.com/MetaMask/metamask-extension/pull/15748)) +- Add new zh_TW translations and apply a variety of fixes ([#11212](https://github.com/MetaMask/metamask-extension/pull/11212)) +- Add ES translations for getting Ethereum Accounts permission message ([#15660](https://github.com/MetaMask/metamask-extension/pull/15660)) +- Add "Verify contract details" link to SetApprovalForAll confirmation screens ([#15756](https://github.com/MetaMask/metamask-extension/pull/15756)) +- Add Reject Transactions modal to be present in the footer of the Approve screen ([#16832](https://github.com/MetaMask/metamask-extension/pull/16832)) - [FLASK] Add snap alerts and prompts via `snap_dialog` RPC method ([#16048](https://github.com/MetaMask/metamask-extension/pull/16048)) -- Use NETWORK_EVENTS.NETWORK_DID_CHANGE to trigger network change callback in assetsContractController ([#16760](https://github.com/MetaMask/metamask-extension/pull/16760)) - [FLASK] Expose transaction origin to transaction insight snaps ([#16671](https://github.com/MetaMask/metamask-extension/pull/16671)) -- Fix production builds for Flask ([#16757](https://github.com/MetaMask/metamask-extension/pull/16757)) + +### Changed +- Update secondary copy and remove the Address component from SetApprovalForAll and NFT Approve screens ([#16292](https://github.com/MetaMask/metamask-extension/pull/16292)) +- Update background color for picker network ([#16466](https://github.com/MetaMask/metamask-extension/pull/16466)) +- Update network colors with design tokens ([#16543](https://github.com/MetaMask/metamask-extension/pull/16543)) +- Update all background-default hovers colors ([#16519](https://github.com/MetaMask/metamask-extension/pull/16519)) - Update signature request screens ([#15776](https://github.com/MetaMask/metamask-extension/pull/15776)) -- remove rpc urls from metrics ([#16710](https://github.com/MetaMask/metamask-extension/pull/16710)) -- Add signature request warning modal ([#16225](https://github.com/MetaMask/metamask-extension/pull/16225)) -- Show account name when qr scan in send screen ([#16204](https://github.com/MetaMask/metamask-extension/pull/16204)) -- Fixes 'yarn start' on Windows - LavaPack is not defined (#13318) ([#13318](https://github.com/MetaMask/metamask-extension/pull/13318)) -- Remove fenced code in TypeScript files ([#16742](https://github.com/MetaMask/metamask-extension/pull/16742)) -- [FLASK] Create E2E test for snap management ([#16628](https://github.com/MetaMask/metamask-extension/pull/16628)) -- [FLASK] `snaps-monorepo@0.25.0` ([#16673](https://github.com/MetaMask/metamask-extension/pull/16673)) -- Fix: multiple reject on the signature request screen ([#16199](https://github.com/MetaMask/metamask-extension/pull/16199)) -- Label house keeping updates ([#16680](https://github.com/MetaMask/metamask-extension/pull/16680)) -- HelpText house keeping updates ([#16681](https://github.com/MetaMask/metamask-extension/pull/16681)) -- Update codeowners to reflect importance of review ([#16665](https://github.com/MetaMask/metamask-extension/pull/16665)) -- Use Webpack 5 for Storybook ([#16678](https://github.com/MetaMask/metamask-extension/pull/16678)) -- Not use hardware keyring classes when initializing KeyringController in extension MV3 version ([#16684](https://github.com/MetaMask/metamask-extension/pull/16684)) -- DAPP action replay improvements ([#16250](https://github.com/MetaMask/metamask-extension/pull/16250)) -- fix issue preventing switching to localhost ([#16707](https://github.com/MetaMask/metamask-extension/pull/16707)) -- Continue converting tests from enzyme to @testing-library/react ([#16458](https://github.com/MetaMask/metamask-extension/pull/16458)) -- Restore open api usage fully by snow ([#16722](https://github.com/MetaMask/metamask-extension/pull/16722)) -- Unable to proceed with tx bc of inaccurate/overly aggressive "Insufficient funds for gas" warning #13087 ([#14634](https://github.com/MetaMask/metamask-extension/pull/14634)) -- [e2e] Setup MV3 specific test folder and add 1 simple testcase introducing Service Worker re-start ([#16606](https://github.com/MetaMask/metamask-extension/pull/16606)) -- Token allowance i18n interpolation system ([#16347](https://github.com/MetaMask/metamask-extension/pull/16347)) -- Migrate to new controller packages ([#16547](https://github.com/MetaMask/metamask-extension/pull/16547)) -- Resetting spending cap value to empty when a token allowance request is rejected. ([#16659](https://github.com/MetaMask/metamask-extension/pull/16659)) -- Mitigate flaky test with the use of new function ([#16655](https://github.com/MetaMask/metamask-extension/pull/16655)) -- [e2e] [MV3] Fix Add Account e2e flaky test for MV3 build ([#16603](https://github.com/MetaMask/metamask-extension/pull/16603)) -- Master sync following v10.22.3 ([#16650](https://github.com/MetaMask/metamask-extension/pull/16650)) -- Simplify MV3 initialization ([#16559](https://github.com/MetaMask/metamask-extension/pull/16559)) -- Fix #15050 - MV3: Keep the user logged in when service worker restarts ([#15558](https://github.com/MetaMask/metamask-extension/pull/15558)) -- Integrating snow into metamask ([#15580](https://github.com/MetaMask/metamask-extension/pull/15580)) -- fix infura rpc detection ([#16585](https://github.com/MetaMask/metamask-extension/pull/16585)) -- Remove callback from being saved in controller state ([#16627](https://github.com/MetaMask/metamask-extension/pull/16627)) -- Icon house keeping updates ([#16621](https://github.com/MetaMask/metamask-extension/pull/16621)) -- Fix bundle size diff message ([#16576](https://github.com/MetaMask/metamask-extension/pull/16576)) -- avatar base component housekeeping ([#16583](https://github.com/MetaMask/metamask-extension/pull/16583)) -- Disabled save button on add contact form if input fields are empty ([#16233](https://github.com/MetaMask/metamask-extension/pull/16233)) -- Fix E2E chunking ([#16653](https://github.com/MetaMask/metamask-extension/pull/16653)) -- Fix develop conflicts -- fixed console warning for labelProps ([#16629](https://github.com/MetaMask/metamask-extension/pull/16629)) -- Adding `FormTextField` component ([#16497](https://github.com/MetaMask/metamask-extension/pull/16497)) -- Fix/16620/button href prop ([#16633](https://github.com/MetaMask/metamask-extension/pull/16633)) -- Keep memstore contents after service worker restarts ([#15913](https://github.com/MetaMask/metamask-extension/pull/15913)) -- Adding ITA translations ([#15748](https://github.com/MetaMask/metamask-extension/pull/15748)) +- Remove network name from analytics ([#16781](https://github.com/MetaMask/metamask-extension/pull/16781)) +- Remove RPC urls from metrics ([#16710](https://github.com/MetaMask/metamask-extension/pull/16710)) +- Allow adding networks with the same chainId as a preloaded/default network via `wallet_AddEthereumChain` API ([#16733](https://github.com/MetaMask/metamask-extension/pull/16733)) +- Network request in background should not start until onboarding is completed ([#16773](https://github.com/MetaMask/metamask-extension/pull/16773)) +- Replace the address in SignTypedData_v4 signatures with a 'Verify contract details' link ([#16191](https://github.com/MetaMask/metamask-extension/pull/16191)) +- Bump `@metamask/design-tokens` from `1.11.0` to `1.11.1` ([#16764](https://github.com/MetaMask/metamask-extension/pull/16764)) +- Bump `@metamask/design-tokens` from `1.9.0` to `1.11.0` ([#16515](https://github.com/MetaMask/metamask-extension/pull/16515)) +- Update `@metamask/controllers` to `v33` ([#16493](https://github.com/MetaMask/metamask-extension/pull/16493)) +- Migrate from deprecated `@metamask/controllers`to the new controller packages ([#16547](https://github.com/MetaMask/metamask-extension/pull/16547)) +- Swaps: ensure 0% slippage on Arbitrum for wrapping/unwrapping ETH (ETH -> WETH or WETH -> ETH) ([#16778](https://github.com/MetaMask/metamask-extension/pull/16778)) +- [Beta] Update `BETA` to sentence case ([#16590](https://github.com/MetaMask/metamask-extension/pull/16590)) +- [Beta] Update text on the Welcome screen ([#16489](https://github.com/MetaMask/metamask-extension/pull/16489)) +- [FLASK] **BREAKING:** Snaps are now required to request the `endowment:rpc` permission to receive RPC requests on `onRpcRequest` ([#16673](https://github.com/MetaMask/metamask-extension/pull/16673)) + - Snaps must specify if they want to receive RPC requests from dapps or snaps using the following permission `endowment:rpc: { dapps: true, snaps: true }` +- [FLASK] **BREAKING:** Removed `wallet_enable` and `wallet_installSnaps` in favor of `wallet_requestSnaps` ([#16525](https://github.com/MetaMask/metamask-extension/pull/16525)) +- [FLASK] **BREAKING:** The `wallet` global exposed to Snaps has been replaced with two new globals: `snap` and `ethereum` ([#16525](https://github.com/MetaMask/metamask-extension/pull/16525)) + - `ethereum` is an EIP-1193 provider and can be accessed by requesting the `endowment:ethereum-provider` permission + - `snap` is always exposed and can be used to access snap specific functions using `snap.request()` +- [FLASK] **BREAKING:** Named parameters are now required in all Snaps RPC methods ([#16525](https://github.com/MetaMask/metamask-extension/pull/16525)) + +### Removed +- [FLASK] **BREAKING:** Removed `snap_getAppKey` ([#16525](https://github.com/MetaMask/metamask-extension/pull/16525)) + - Snaps that need snap-specific entropy can use `snap_getEntropy` instead + +### Fixed +- Fix resolving to the Account nickname or contact name when scanning the QR code in the Send screen ([#16204](https://github.com/MetaMask/metamask-extension/pull/16204)) +- Fix not being able to reject multiple Signature requests ([#16199](https://github.com/MetaMask/metamask-extension/pull/16199)) +- Fix issue that prevents switching to localhost using the API ([#16707](https://github.com/MetaMask/metamask-extension/pull/16707)) +- Fix unable to proceed with tx when there is "Insufficient funds for gas", by adding the estimated gas fee section on the Send screen ([#14634](https://github.com/MetaMask/metamask-extension/pull/14634)) +- Fix Add Contact by disabling the Save button if the input fields are empty ([#16233](https://github.com/MetaMask/metamask-extension/pull/16233)) +- Fix Token Detection displaying a token without balance, by updating the user state `tokensChainsCache` from array to object ([#16535](https://github.com/MetaMask/metamask-extension/pull/16535)) +- Fix message not rendering properly on Sign Typed Data v4 screen, by supporting nested arrays and arrays with defined length ([#16552](https://github.com/MetaMask/metamask-extension/pull/16552)) +- Fix German translation for `lightTheme` ([#16517](https://github.com/MetaMask/metamask-extension/pull/16517)) - [FLASK] Clear notification state on restore ([#16503](https://github.com/MetaMask/metamask-extension/pull/16503)) - [FLASK] Fix a crash that happens after snap install ([#16526](https://github.com/MetaMask/metamask-extension/pull/16526)) -- [FLASK] `snaps-monorepo@0.24.1` ([#16525](https://github.com/MetaMask/metamask-extension/pull/16525)) -- added sm border radius ([#16611](https://github.com/MetaMask/metamask-extension/pull/16611)) -- [e2e] [MV3] Fix Custom RPC e2e test failures for MV3 build ([#16599](https://github.com/MetaMask/metamask-extension/pull/16599)) -- Replace the address in SignTypedData_v4 signatures with a 'Verify contract details' link ([#16191](https://github.com/MetaMask/metamask-extension/pull/16191)) -- Expanded permission_ethereumAccounts spanish translation ([#15660](https://github.com/MetaMask/metamask-extension/pull/15660)) -- Make ENS named elements domain generic ([#16166](https://github.com/MetaMask/metamask-extension/pull/16166)) -- Use async/await for extension functions ([#15722](https://github.com/MetaMask/metamask-extension/pull/15722)) -- BETA - Update to sentence case ([#16590](https://github.com/MetaMask/metamask-extension/pull/16590)) -- Create constants for all keyring types ([#16575](https://github.com/MetaMask/metamask-extension/pull/16575)) -- [FLASK] Improve Snaps E2E stability ([#16597](https://github.com/MetaMask/metamask-extension/pull/16597)) -- updated responsive props for border radius ([#16510](https://github.com/MetaMask/metamask-extension/pull/16510)) -- Feat/16507/button link housekeeping ([#16518](https://github.com/MetaMask/metamask-extension/pull/16518)) -- Updating tokensChainsCache[chainId].data to object from array in user state ([#16535](https://github.com/MetaMask/metamask-extension/pull/16535)) -- updated background color for picker network ([#16466](https://github.com/MetaMask/metamask-extension/pull/16466)) -- Adding static icon names to test env file ([#16078](https://github.com/MetaMask/metamask-extension/pull/16078)) -- Fix message on sign typed data v4 screen ([#16552](https://github.com/MetaMask/metamask-extension/pull/16552)) -- Removing storybook tests ([#16577](https://github.com/MetaMask/metamask-extension/pull/16577)) -- Minor scripts/ui.js file cleanup ([#16566](https://github.com/MetaMask/metamask-extension/pull/16566)) -- Updated Text style in Tag Url ([#16570](https://github.com/MetaMask/metamask-extension/pull/16570)) -- Updating network colors with design tokens ([#16543](https://github.com/MetaMask/metamask-extension/pull/16543)) -- Updating all background-default hovers colors ([#16519](https://github.com/MetaMask/metamask-extension/pull/16519)) -- Ensure prod beta build is created when merging to master ([#16557](https://github.com/MetaMask/metamask-extension/pull/16557)) -- MV3: support Service Worker restart for phishing warning pages ([#16488](https://github.com/MetaMask/metamask-extension/pull/16488)) -- Fix crash on e2e test failure ([#16556](https://github.com/MetaMask/metamask-extension/pull/16556)) -- Add transaction security check toggle ([#16271](https://github.com/MetaMask/metamask-extension/pull/16271)) -- Skip the first token allowance screen if dapp proposing spending cap is 0 ([#16502](https://github.com/MetaMask/metamask-extension/pull/16502)) -- Master sync following v10.22.2 ([#16548](https://github.com/MetaMask/metamask-extension/pull/16548)) -- Merge remote-tracking branch 'origin/develop' into master-sync -- Component library adding global index and other housekeeping ([#16441](https://github.com/MetaMask/metamask-extension/pull/16441)) -- fix(i18n): de lightTheme translation ([#16517](https://github.com/MetaMask/metamask-extension/pull/16517)) -- [FLASK] Update e2e tests for new react test-snaps page ([#16324](https://github.com/MetaMask/metamask-extension/pull/16324)) -- [e2e] Fix RPC flaky test ([#16530](https://github.com/MetaMask/metamask-extension/pull/16530)) -- BETA - Updating welcome message ([#16489](https://github.com/MetaMask/metamask-extension/pull/16489)) -- Bump @metamask/design-tokens from 1.9.0 to 1.11.0 ([#16515](https://github.com/MetaMask/metamask-extension/pull/16515)) -- Add mocks for E2E tests ([#16527](https://github.com/MetaMask/metamask-extension/pull/16527)) -- Modified chain_id value(MetaMetrics), in the Custom Network Added event ([#16426](https://github.com/MetaMask/metamask-extension/pull/16426)) -- Remove unnecessary await ([#16482](https://github.com/MetaMask/metamask-extension/pull/16482)) -- persist user traits for comparison ([#16506](https://github.com/MetaMask/metamask-extension/pull/16506)) -- Configure smart transactions controller to support goerli ([#16500](https://github.com/MetaMask/metamask-extension/pull/16500)) -- button secondary housekeeping ([#16495](https://github.com/MetaMask/metamask-extension/pull/16495)) -- Added "What's New" Notification for Improved token allowance experience ([#16465](https://github.com/MetaMask/metamask-extension/pull/16465)) -- Update `@metamask/controllers` to v33 ([#16493](https://github.com/MetaMask/metamask-extension/pull/16493)) -- Jest: Add browser.runtime (webextension-polyfill) utils tests ([#16483](https://github.com/MetaMask/metamask-extension/pull/16483)) -- Adding some propType fixes to `TextFieldBase` ([#16508](https://github.com/MetaMask/metamask-extension/pull/16508)) -- Adding `TextFieldSearch` component ([#16296](https://github.com/MetaMask/metamask-extension/pull/16296)) -- upgrade gulp-autoprefixer ([#16439](https://github.com/MetaMask/metamask-extension/pull/16439)) -- Feat/16185/button primary housekeeping ([#16457](https://github.com/MetaMask/metamask-extension/pull/16457)) -- added 50% border radius support to the Box component ([#16486](https://github.com/MetaMask/metamask-extension/pull/16486)) -- [i18n:zh_tw] Sync and update translation for zh_TW ([#11212](https://github.com/MetaMask/metamask-extension/pull/11212)) -- Added a 'Verify contract details' link to SetApprovalForAll confirmation screens ([#15756](https://github.com/MetaMask/metamask-extension/pull/15756)) -- MV3: Update service worker restart logic and keep-alive logic for dapp support ([#16075](https://github.com/MetaMask/metamask-extension/pull/16075)) +- [FLASK] Fix usage of wrong `ethereum` global for `ethereum` endowment ([#16932](https://github.com/MetaMask/metamask-extension/pull/16932)) ## [10.23.0] ### Added From 5accaf88b9ea8fea646efe90cd9d8ccdf85e2f70 Mon Sep 17 00:00:00 2001 From: Alex Donesky Date: Wed, 14 Dec 2022 19:20:55 -0600 Subject: [PATCH 15/78] add back error when password is too short (#16876) --- .../create-password/create-password.js | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/ui/pages/onboarding-flow/create-password/create-password.js b/ui/pages/onboarding-flow/create-password/create-password.js index b31858de1168..369d45ead4f4 100644 --- a/ui/pages/onboarding-flow/create-password/create-password.js +++ b/ui/pages/onboarding-flow/create-password/create-password.js @@ -85,13 +85,14 @@ export default function CreatePassword({ const handlePasswordChange = (passwordInput) => { let confirmError = ''; + let passwordInputError = ''; const passwordEvaluation = zxcvbn(passwordInput); const passwordStrengthLabel = getPasswordStrengthLabel( passwordEvaluation.score, t, ); - const passwordStrengthDescription = passwordStrengthLabel.description; - const passwordStrengthInput = t('passwordStrength', [ + let passwordStrengthDescription = passwordStrengthLabel.description; + let passwordStrengthInput = t('passwordStrength', [ , ]); + if (passwordInput.length < 8) { + passwordInputError = passwordInput.length + ? t('passwordNotLongEnough') + : ''; + passwordStrengthInput = null; + passwordStrengthDescription = ''; + } + if (confirmPassword && passwordInput !== confirmPassword) { confirmError = t('passwordsDontMatch'); } setPassword(passwordInput); + setPasswordError(passwordInputError); setPasswordStrength(passwordStrengthInput); setPasswordStrengthText(passwordStrengthDescription); setConfirmPasswordError(confirmError); @@ -175,6 +185,7 @@ export default function CreatePassword({ Date: Thu, 15 Dec 2022 08:38:15 -0600 Subject: [PATCH 16/78] Onboarding: Set SeedPhraseBackedUp when appropriate (#16875) * Onboarding: Set SeedPhraseBackedUp when appropriate * Dispatch setSeedPhraseBackedUp * Fix test * Make call async * Fix test * Fix test * enhance test Co-authored-by: Alex --- .../recovery-phrase/confirm-recovery-phrase.js | 6 +++++- .../secure-your-wallet/secure-your-wallet.test.js | 15 ++++++++++++--- .../secure-your-wallet/skip-srp-backup-popover.js | 9 ++++++++- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/ui/pages/onboarding-flow/recovery-phrase/confirm-recovery-phrase.js b/ui/pages/onboarding-flow/recovery-phrase/confirm-recovery-phrase.js index ccd4ca2e40b5..2523e5da586f 100644 --- a/ui/pages/onboarding-flow/recovery-phrase/confirm-recovery-phrase.js +++ b/ui/pages/onboarding-flow/recovery-phrase/confirm-recovery-phrase.js @@ -1,5 +1,6 @@ import React, { useState, useMemo } from 'react'; import { useHistory } from 'react-router-dom'; +import { useDispatch } from 'react-redux'; import { debounce } from 'lodash'; import PropTypes from 'prop-types'; import Box from '../../../components/ui/box'; @@ -17,11 +18,13 @@ import { } from '../../../components/app/step-progress-bar'; import { ONBOARDING_COMPLETION_ROUTE } from '../../../helpers/constants/routes'; import { useI18nContext } from '../../../hooks/useI18nContext'; +import { setSeedPhraseBackedUp } from '../../../store/actions'; import RecoveryPhraseChips from './recovery-phrase-chips'; export default function ConfirmRecoveryPhrase({ secretRecoveryPhrase = '' }) { const history = useHistory(); const t = useI18nContext(); + const dispatch = useDispatch(); const splitSecretRecoveryPhrase = secretRecoveryPhrase.split(' '); const indicesToCheck = [2, 3, 7]; const [matching, setMatching] = useState(false); @@ -93,7 +96,8 @@ export default function ConfirmRecoveryPhrase({ secretRecoveryPhrase = '' }) { type="primary" large className="recovery-phrase__footer__confirm--button" - onClick={() => { + onClick={async () => { + await dispatch(setSeedPhraseBackedUp(true)); history.push(ONBOARDING_COMPLETION_ROUTE); }} disabled={!matching} diff --git a/ui/pages/onboarding-flow/secure-your-wallet/secure-your-wallet.test.js b/ui/pages/onboarding-flow/secure-your-wallet/secure-your-wallet.test.js index 1622f8069f79..cecbda1a0886 100644 --- a/ui/pages/onboarding-flow/secure-your-wallet/secure-your-wallet.test.js +++ b/ui/pages/onboarding-flow/secure-your-wallet/secure-your-wallet.test.js @@ -1,9 +1,11 @@ import React from 'react'; import { fireEvent } from '@testing-library/react'; import configureMockStore from 'redux-mock-store'; +import thunk from 'redux-thunk'; import reactRouterDom from 'react-router-dom'; import { renderWithProvider } from '../../../../test/lib/render-helpers'; import { ONBOARDING_COMPLETION_ROUTE } from '../../../helpers/constants/routes'; +import * as Actions from '../../../store/actions'; import SecureYourWallet from './secure-your-wallet'; describe('Secure Your Wallet Onboarding View', () => { @@ -28,7 +30,8 @@ describe('Secure Your Wallet Onboarding View', () => { }, }; - const store = configureMockStore()(mockStore); + const store = configureMockStore([thunk])(mockStore); + it('should show a popover asking the user if they want to skip account security if they click "Remind me later"', () => { const { queryAllByText, getByText } = renderWithProvider( , @@ -40,7 +43,11 @@ describe('Secure Your Wallet Onboarding View', () => { expect(queryAllByText('Skip account security?')).toHaveLength(1); }); - it('should not be able to click "skip" until "Skip Account Security" terms are agreed to', () => { + it('should not be able to click "skip" until "Skip Account Security" terms are agreed to', async () => { + const setSeedPhraseBackedUpSpy = jest + .spyOn(Actions, 'setSeedPhraseBackedUp') + .mockReturnValue({ type: 'setSeedPhraseBackedUp' }); + const { getByText, getByTestId } = renderWithProvider( , store, @@ -52,7 +59,9 @@ describe('Secure Your Wallet Onboarding View', () => { expect(pushMock).toHaveBeenCalledTimes(0); const checkbox = getByTestId('skip-srp-backup-popover-checkbox'); fireEvent.click(checkbox); - fireEvent.click(skipButton); + const confirmSkip = getByTestId('skip-srp-backup'); + await fireEvent.click(confirmSkip); + expect(setSeedPhraseBackedUpSpy).toHaveBeenCalledTimes(1); expect(pushMock).toHaveBeenCalledTimes(1); expect(pushMock).toHaveBeenCalledWith(ONBOARDING_COMPLETION_ROUTE); }); diff --git a/ui/pages/onboarding-flow/secure-your-wallet/skip-srp-backup-popover.js b/ui/pages/onboarding-flow/secure-your-wallet/skip-srp-backup-popover.js index 1557d5388959..2020962135c8 100644 --- a/ui/pages/onboarding-flow/secure-your-wallet/skip-srp-backup-popover.js +++ b/ui/pages/onboarding-flow/secure-your-wallet/skip-srp-backup-popover.js @@ -1,6 +1,7 @@ import React, { useState } from 'react'; import PropTypes from 'prop-types'; import { useHistory } from 'react-router-dom'; +import { useDispatch } from 'react-redux'; import { useI18nContext } from '../../../hooks/useI18nContext'; import Button from '../../../components/ui/button'; import Popover from '../../../components/ui/popover'; @@ -13,6 +14,7 @@ import { JUSTIFY_CONTENT, TYPOGRAPHY, } from '../../../helpers/constants/design-system'; +import { setSeedPhraseBackedUp } from '../../../store/actions'; import Checkbox from '../../../components/ui/check-box'; import { ONBOARDING_COMPLETION_ROUTE } from '../../../helpers/constants/routes'; @@ -20,6 +22,8 @@ export default function SkipSRPBackup({ handleClose }) { const [checked, setChecked] = useState(false); const t = useI18nContext(); const history = useHistory(); + const dispatch = useDispatch(); + return ( history.push(ONBOARDING_COMPLETION_ROUTE)} + onClick={async () => { + await dispatch(setSeedPhraseBackedUp(false)); + history.push(ONBOARDING_COMPLETION_ROUTE); + }} > {t('skip')} From 557b5de08dd7e82c3634df519136c4f6210feb45 Mon Sep 17 00:00:00 2001 From: Dan J Miller Date: Fri, 16 Dec 2022 11:56:23 -0330 Subject: [PATCH 17/78] Sanitize privacy sensitive data before sending to sentry. (#16780) * Sanitize privacy sensitive data before sending to sentry. Temp Near complete Complete * Temp * Fix url error message rewrite * Add unit tests and cleanup code * Improvements * Update app/scripts/lib/setupSentry.js Co-authored-by: Mark Stacey * Update app/scripts/lib/setupSentry.js Co-authored-by: Mark Stacey * Update app/scripts/lib/setupSentry.js Co-authored-by: Mark Stacey * Fix syntax of doc comments * Catch errors caused by invalid urls in sanitizeUrlsFromErrorMessages * Ensure our allowlist matches multiple subdomains * Ensure sanitizeUrlsFromErrorMessages correctly matches hostnames * Update app/scripts/lib/setupSentry.js Co-authored-by: Mark Stacey * Improve test descriptions * fix Co-authored-by: Ariella Vu <20778143+digiwand@users.noreply.github.com> Co-authored-by: Mark Stacey --- app/scripts/lib/setupSentry.js | 149 ++++++++++++++--- app/scripts/lib/setupSentry.test.js | 241 ++++++++++++++++++++++++++++ 2 files changed, 370 insertions(+), 20 deletions(-) create mode 100644 app/scripts/lib/setupSentry.test.js diff --git a/app/scripts/lib/setupSentry.js b/app/scripts/lib/setupSentry.js index 73bad861c84f..7ed335bd08ca 100644 --- a/app/scripts/lib/setupSentry.js +++ b/app/scripts/lib/setupSentry.js @@ -16,6 +16,14 @@ const METAMASK_BUILD_TYPE = process.env.METAMASK_BUILD_TYPE; const IN_TEST = process.env.IN_TEST; /* eslint-enable prefer-destructuring */ +export const ERROR_URL_ALLOWLIST = { + CRYPTOCOMPARE: 'cryptocompare.com', + COINGECKO: 'coingecko.com', + ETHERSCAN: 'etherscan.io', + CODEFI: 'codefi.network', + SEGMENT: 'segment.io', +}; + // This describes the subset of Redux state attached to errors sent to Sentry // These properties have some potential to be useful for debugging, and they do // not contain any identifiable information. @@ -131,7 +139,7 @@ export default function setupSentry({ release, getState }) { new ExtraErrorData(), ], release, - beforeSend: (report) => rewriteReport(report), + beforeSend: (report) => rewriteReport(report, getState), beforeBreadcrumb(breadcrumb) { if (getState) { const appState = getState(); @@ -146,31 +154,132 @@ export default function setupSentry({ release, getState }) { } else { return null; } - return breadcrumb; + const newBreadcrumb = removeUrlsFromBreadCrumb(breadcrumb); + return newBreadcrumb; }, }); - function rewriteReport(report) { - try { - // simplify certain complex error messages (e.g. Ethjs) - simplifyErrorMessages(report); - // modify report urls - rewriteReportUrls(report); - // append app state - if (getState) { - const appState = getState(); - if (!report.extra) { - report.extra = {}; - } - report.extra.appState = appState; + return Sentry; +} + +/** + * Receives a string and returns that string if it is a + * regex match for a url with a `chrome-extension` or `moz-extension` + * protocol, and an empty string otherwise. + * + * @param {string} url - The URL to check. + * @returns {string} An empty string if the URL was internal, or the unmodified URL otherwise. + */ +function hideUrlIfNotInternal(url) { + const re = /^(chrome-extension|moz-extension):\/\//u; + if (!url.match(re)) { + return ''; + } + return url; +} + +/** + * Receives a Sentry breadcrumb object and potentially removes urls + * from its `data` property, it particular those possibly found at + * data.from, data.to and data.url + * + * @param {object} breadcrumb - A Sentry breadcrumb object: https://develop.sentry.dev/sdk/event-payloads/breadcrumbs/ + * @returns {object} A modified Sentry breadcrumb object. + */ +export function removeUrlsFromBreadCrumb(breadcrumb) { + if (breadcrumb?.data?.url) { + breadcrumb.data.url = hideUrlIfNotInternal(breadcrumb.data.url); + } + if (breadcrumb?.data?.to) { + breadcrumb.data.to = hideUrlIfNotInternal(breadcrumb.data.to); + } + if (breadcrumb?.data?.from) { + breadcrumb.data.from = hideUrlIfNotInternal(breadcrumb.data.from); + } + return breadcrumb; +} + +/** + * Receives a Sentry event object and modifies it before the + * error is sent to Sentry. Modifications include both sanitization + * of data via helper methods and addition of state data from the + * return value of the second parameter passed to the function. + * + * @param {object} report - A Sentry event object: https://develop.sentry.dev/sdk/event-payloads/ + * @param {Function} getState - A function that should return an object representing some amount + * of app state that we wish to submit with our error reports + * @returns {object} A modified Sentry event object. + */ +export function rewriteReport(report, getState) { + try { + // simplify certain complex error messages (e.g. Ethjs) + simplifyErrorMessages(report); + // remove urls from error message + sanitizeUrlsFromErrorMessages(report); + // Remove evm addresses from error message. + // Note that this is redundent with data scrubbing we do within our sentry dashboard, + // but putting the code here as well gives public visibility to how we are handling + // privacy with respect to sentry. + sanitizeAddressesFromErrorMessages(report); + // modify report urls + rewriteReportUrls(report); + // append app state + if (getState) { + const appState = getState(); + if (!report.extra) { + report.extra = {}; } - } catch (err) { - console.warn(err); + report.extra.appState = appState; } - return report; + } catch (err) { + console.warn(err); } + return report; +} - return Sentry; +/** + * Receives a Sentry event object and modifies it so that urls are removed from any of its + * error messages. + * + * @param {object} report - the report to modify + */ +function sanitizeUrlsFromErrorMessages(report) { + rewriteErrorMessages(report, (errorMessage) => { + let newErrorMessage = errorMessage; + const re = /(([-.+a-zA-Z]+:\/\/)|(www\.))\S+[@:.]\S+/gu; + const urlsInMessage = newErrorMessage.match(re) || []; + urlsInMessage.forEach((url) => { + try { + const urlObj = new URL(url); + const { hostname } = urlObj; + if ( + !Object.values(ERROR_URL_ALLOWLIST).some( + (allowedHostname) => + hostname === allowedHostname || + hostname.endsWith(`.${allowedHostname}`), + ) + ) { + newErrorMessage = newErrorMessage.replace(url, '**'); + } + } catch (e) { + newErrorMessage = newErrorMessage.replace(url, '**'); + } + }); + return newErrorMessage; + }); +} + +/** + * Receives a Sentry event object and modifies it so that ethereum addresses are removed from + * any of its error messages. + * + * @param {object} report - the report to modify + */ +function sanitizeAddressesFromErrorMessages(report) { + rewriteErrorMessages(report, (errorMessage) => { + const newErrorMessage = errorMessage.replace(/0x[A-Fa-f0-9]{40}/u, '0x**'); + return newErrorMessage; + }); } function simplifyErrorMessages(report) { @@ -221,7 +330,7 @@ function rewriteReportUrls(report) { } function toMetamaskUrl(origUrl) { - const filePath = origUrl.split(globalThis.location.origin)[1]; + const filePath = origUrl?.split(globalThis.location.origin)[1]; if (!filePath) { return origUrl; } diff --git a/app/scripts/lib/setupSentry.test.js b/app/scripts/lib/setupSentry.test.js new file mode 100644 index 000000000000..f8ab7fd32be1 --- /dev/null +++ b/app/scripts/lib/setupSentry.test.js @@ -0,0 +1,241 @@ +import { rewriteReport, removeUrlsFromBreadCrumb } from './setupSentry'; + +describe('Setup Sentry', () => { + describe('rewriteReport', () => { + it('should remove urls from error messages', () => { + const testReport = { + message: 'This report has a test url: http://example.com', + request: {}, + }; + const rewrittenReport = rewriteReport(testReport); + expect(rewrittenReport.message).toStrictEqual( + 'This report has a test url: **', + ); + }); + + it('should remove urls from error reports that have an exception with an array of values', () => { + const testReport = { + exception: { + values: [ + { + value: 'This report has a test url: http://example.com', + }, + { + value: 'https://example.com is another url', + }, + ], + }, + request: {}, + }; + const rewrittenReport = rewriteReport(testReport); + expect(rewrittenReport.exception.values).toStrictEqual([ + { + value: 'This report has a test url: **', + }, + { + value: '** is another url', + }, + ]); + }); + + it('should remove ethereum addresses from error messages', () => { + const testReport = { + message: + 'There is an ethereum address 0x790A8A9E9bc1C9dB991D8721a92e461Db4CfB235 in this message', + request: {}, + }; + const rewrittenReport = rewriteReport(testReport); + expect(rewrittenReport.message).toStrictEqual( + 'There is an ethereum address 0x** in this message', + ); + }); + + it('should not remove urls from our allow list', () => { + const testReport = { + message: 'This report has an allowed url: https://codefi.network/', + request: {}, + }; + const rewrittenReport = rewriteReport(testReport); + expect(rewrittenReport.message).toStrictEqual( + 'This report has an allowed url: https://codefi.network/', + ); + }); + + it('should not remove urls at subdomains of the urls in the allow list', () => { + const testReport = { + message: + 'This report has an allowed url: https://subdomain.codefi.network/', + request: {}, + }; + const rewrittenReport = rewriteReport(testReport); + expect(rewrittenReport.message).toStrictEqual( + 'This report has an allowed url: https://subdomain.codefi.network/', + ); + }); + + it('should remove urls very similar to, but different from, those in our allow list', () => { + const testReport = { + message: + 'This report does not have an allowed url: https://nodefi.network/', + request: {}, + }; + const rewrittenReport = rewriteReport(testReport); + expect(rewrittenReport.message).toStrictEqual( + 'This report does not have an allowed url: **', + ); + }); + + it('should remove urls with allow list urls in their domain path', () => { + const testReport = { + message: + 'This report does not have an allowed url: https://codefi.network.another.domain.com/', + request: {}, + }; + const rewrittenReport = rewriteReport(testReport); + expect(rewrittenReport.message).toStrictEqual( + 'This report does not have an allowed url: **', + ); + }); + + it('should remove urls have allowed urls in their URL path', () => { + const testReport = { + message: + 'This report does not have an allowed url: https://example.com/test?redirect=http://codefi.network', + request: {}, + }; + const rewrittenReport = rewriteReport(testReport); + expect(rewrittenReport.message).toStrictEqual( + 'This report does not have an allowed url: **', + ); + }); + + it('should remove urls with subdomains', () => { + const testReport = { + message: + 'This report does not have an allowed url: https://subdomain.example.com/', + request: {}, + }; + const rewrittenReport = rewriteReport(testReport); + expect(rewrittenReport.message).toStrictEqual( + 'This report does not have an allowed url: **', + ); + }); + + it('should remove invalid urls', () => { + const testReport = { + message: + 'This report does not have an allowed url: https://example.%%%/', + request: {}, + }; + const rewrittenReport = rewriteReport(testReport); + expect(rewrittenReport.message).toStrictEqual( + 'This report does not have an allowed url: **', + ); + }); + + it('should remove urls and ethereum addresses from error messages', () => { + const testReport = { + message: + 'This 0x790A8A9E9bc1C9dB991D8721a92e461Db4CfB235 address used http://example.com on Saturday', + request: {}, + }; + const rewrittenReport = rewriteReport(testReport); + expect(rewrittenReport.message).toStrictEqual( + 'This 0x** address used ** on Saturday', + ); + }); + + it('should not modify an error message with no urls or addresses', () => { + const testReport = { + message: 'This is a simple report', + request: {}, + }; + const rewrittenReport = rewriteReport(testReport); + expect(rewrittenReport.message).toStrictEqual('This is a simple report'); + }); + }); + + describe('removeUrlsFromBreadCrumb', () => { + it('should hide the breadcrumb data url', () => { + const testBreadcrumb = { + data: { + url: 'https://example.com', + }, + }; + const rewrittenBreadcrumb = removeUrlsFromBreadCrumb(testBreadcrumb); + expect(rewrittenBreadcrumb.data.url).toStrictEqual(''); + }); + + it('should hide the breadcrumb data "to" page', () => { + const testBreadcrumb = { + data: { + to: 'https://example.com', + }, + }; + const rewrittenBreadcrumb = removeUrlsFromBreadCrumb(testBreadcrumb); + expect(rewrittenBreadcrumb.data.to).toStrictEqual(''); + }); + + it('should hide the breadcrumb data "from" page', () => { + const testBreadcrumb = { + data: { + from: 'https://example.com', + }, + }; + const rewrittenBreadcrumb = removeUrlsFromBreadCrumb(testBreadcrumb); + expect(rewrittenBreadcrumb.data.from).toStrictEqual(''); + }); + + it('should NOT hide the breadcrumb data url if the url is on the extension protocol', () => { + const testBreadcrumb = { + data: { + url: 'chrome-extension://abcefg/home.html', + }, + }; + const rewrittenBreadcrumb = removeUrlsFromBreadCrumb(testBreadcrumb); + expect(rewrittenBreadcrumb.data.url).toStrictEqual( + 'chrome-extension://abcefg/home.html', + ); + }); + + it('should NOT hide the breadcrumb data "to" page if the url is on the extension protocol', () => { + const testBreadcrumb = { + data: { + to: 'chrome-extension://abcefg/home.html', + }, + }; + const rewrittenBreadcrumb = removeUrlsFromBreadCrumb(testBreadcrumb); + expect(rewrittenBreadcrumb.data.to).toStrictEqual( + 'chrome-extension://abcefg/home.html', + ); + }); + + it('should NOT hide the breadcrumb data "from" page if the url is on the extension protocol', () => { + const testBreadcrumb = { + data: { + from: 'chrome-extension://abcefg/home.html', + }, + }; + const rewrittenBreadcrumb = removeUrlsFromBreadCrumb(testBreadcrumb); + expect(rewrittenBreadcrumb.data.from).toStrictEqual( + 'chrome-extension://abcefg/home.html', + ); + }); + + it('should hide "to" but not "from" or url if "to" is the only one not matching an internal url', () => { + const testBreadcrumb = { + data: { + url: 'chrome-extension://abcefg/home.html', + to: 'https://example.com', + from: 'chrome-extension://abcefg/home.html', + }, + }; + const rewrittenBreadcrumb = removeUrlsFromBreadCrumb(testBreadcrumb); + expect(rewrittenBreadcrumb.data).toStrictEqual({ + url: 'chrome-extension://abcefg/home.html', + to: '', + from: 'chrome-extension://abcefg/home.html', + }); + }); + }); +}); From 60bfdf51d68ec88c02b11cb2f2de868b6ef5edb8 Mon Sep 17 00:00:00 2001 From: Dan J Miller Date: Fri, 16 Dec 2022 13:37:18 -0330 Subject: [PATCH 18/78] remove warning on revoke approval for all nfts (#16953) Co-authored-by: EresDev --- test/e2e/tests/collectibles.spec.js | 1 - .../confirm-page-container.component.js | 8 +++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/test/e2e/tests/collectibles.spec.js b/test/e2e/tests/collectibles.spec.js index b00ee7100d2e..c8e5484fb419 100644 --- a/test/e2e/tests/collectibles.spec.js +++ b/test/e2e/tests/collectibles.spec.js @@ -260,7 +260,6 @@ describe('Collectibles', function () { // Confirm disabling set approval for all await driver.clickElement({ text: 'Confirm', tag: 'button' }); - await driver.clickElement({ text: 'Approve', tag: 'button' }); await driver.waitUntilXWindowHandles(2); await driver.switchToWindow(extension); diff --git a/ui/components/app/confirm-page-container/confirm-page-container.component.js b/ui/components/app/confirm-page-container/confirm-page-container.component.js index 952f21c730e2..81a82ebb496b 100644 --- a/ui/components/app/confirm-page-container/confirm-page-container.component.js +++ b/ui/components/app/confirm-page-container/confirm-page-container.component.js @@ -115,6 +115,7 @@ export default class ConfirmPageContainer extends Component { supportsEIP1559V2: PropTypes.bool, nativeCurrency: PropTypes.string, isBuyableChain: PropTypes.bool, + isApprovalOrRejection: PropTypes.bool, }; async componentDidMount() { @@ -193,6 +194,7 @@ export default class ConfirmPageContainer extends Component { ///: END:ONLY_INCLUDE_IN accountBalance, assetStandard, + isApprovalOrRejection, } = this.props; const showAddToAddressDialog = @@ -386,7 +388,11 @@ export default class ConfirmPageContainer extends Component { Date: Fri, 16 Dec 2022 22:20:05 +0700 Subject: [PATCH 19/78] Fix token balance precision on confirm token approval page from soon-to-be-deprecated token allowance flow (#16934) * ConfirmToken: fix token balance onboarding v1 this UI/UX should be deprecated following PR#16740, maybe v10.25 * TokenApproval: use precision for token balance * EditApproval: calc utilizing existing util --- .../edit-approval-permission.component.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/ui/components/app/modals/edit-approval-permission/edit-approval-permission.component.js b/ui/components/app/modals/edit-approval-permission/edit-approval-permission.component.js index bdc9acce5755..8ab5a7330d5b 100644 --- a/ui/components/app/modals/edit-approval-permission/edit-approval-permission.component.js +++ b/ui/components/app/modals/edit-approval-permission/edit-approval-permission.component.js @@ -6,7 +6,10 @@ import BigNumber from 'bignumber.js'; import Modal from '../../modal'; import Identicon from '../../../ui/identicon'; import TextField from '../../../ui/text-field'; -import { calcTokenAmount } from '../../../../../shared/lib/transactions-controller-utils'; +import { + calcTokenAmount, + toPrecisionWithoutTrailingZeros, +} from '../../../../../shared/lib/transactions-controller-utils'; const MAX_UNSIGNED_256_INT = new BigNumber(2).pow(256).minus(1).toString(10); @@ -70,7 +73,10 @@ export default class EditApprovalPermission extends PureComponent {
- {`${Number(tokenBalance).toPrecision(9)} ${tokenSymbol}`} + {`${toPrecisionWithoutTrailingZeros( + tokenBalance, + 9, + )} ${tokenSymbol}`}
From 281f8e16b97a2b6168dda6717ea698aa63723249 Mon Sep 17 00:00:00 2001 From: seaona Date: Mon, 19 Dec 2022 11:07:23 +0100 Subject: [PATCH 20/78] Changelog sync with master --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 54835b55c955..9bd95394ec42 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -65,6 +65,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [FLASK] Clear notification state on restore ([#16503](https://github.com/MetaMask/metamask-extension/pull/16503)) - [FLASK] Fix a crash that happens after snap install ([#16526](https://github.com/MetaMask/metamask-extension/pull/16526)) - [FLASK] Fix usage of wrong `ethereum` global for `ethereum` endowment ([#16932](https://github.com/MetaMask/metamask-extension/pull/16932)) + ## [10.23.1] ### Fixed - Fix incorrectly displaying "New Contract" instead of the recipient address, on the header from the Confirmation page ([#16961](https://github.com/MetaMask/metamask-extension/pull/16961)) @@ -3400,8 +3401,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added the ability to restore accounts from seed words. [Unreleased]: https://github.com/MetaMask/metamask-extension/compare/v10.24.0...HEAD -[10.24.0]: https://github.com/MetaMask/metamask-extension/compare/v10.23.0...v10.24.0 -[Unreleased]: https://github.com/MetaMask/metamask-extension/compare/v10.23.1...HEAD +[10.24.0]: https://github.com/MetaMask/metamask-extension/compare/v10.23.1...v10.24.0 [10.23.1]: https://github.com/MetaMask/metamask-extension/compare/v10.23.0...v10.23.1 [10.23.0]: https://github.com/MetaMask/metamask-extension/compare/v10.22.3...v10.23.0 [10.22.3]: https://github.com/MetaMask/metamask-extension/compare/v10.22.2...v10.22.3 From cb2f25f76796f80858c59f6f038ebb0dbc0e6503 Mon Sep 17 00:00:00 2001 From: Dan J Miller Date: Mon, 19 Dec 2022 13:38:28 -0330 Subject: [PATCH 21/78] Show user the general contract interaction screen for token approvals, when the asset standard is undefined (#16765) Co-authored-by: Jyoti Puri --- ui/pages/confirm-approve/confirm-approve.js | 4 ++++ .../confirm-transaction-base.component.js | 15 ++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/ui/pages/confirm-approve/confirm-approve.js b/ui/pages/confirm-approve/confirm-approve.js index 12295b3fa930..2fca1653c4d2 100644 --- a/ui/pages/confirm-approve/confirm-approve.js +++ b/ui/pages/confirm-approve/confirm-approve.js @@ -16,6 +16,7 @@ import { getNativeCurrency, isAddressLedger, } from '../../ducks/metamask/metamask'; +import ConfirmContractInteraction from '../confirm-contract-interaction'; import { getCurrentCurrency, getSubjectMetadata, @@ -166,6 +167,9 @@ export default function ConfirmApprove({ if (tokenSymbol === undefined && assetName === undefined) { return ; } + if (assetStandard === undefined) { + return ; + } if (improvedTokenAllowanceEnabled && assetStandard === ERC20) { return ( diff --git a/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js b/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js index 1d3e9e133024..ba1f20ed67ee 100644 --- a/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js +++ b/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js @@ -1165,8 +1165,21 @@ export default class ConfirmTransactionBase extends Component { requestsWaitingText, } = this.getNavigateTxData(); + // This `isTokenApproval` case is added to handle possible rendering of this component from + // confirm-approve.js when `assetStandard` is `undefined`. That will happen if the request to + // get the asset standard fails. In that scenario, confirm-approve.js returns the `` + // component, which in turn returns this `` component. We meed to prevent + // the user from editing the transaction in those cases. + + const isTokenApproval = + txData.type === TRANSACTION_TYPES.TOKEN_METHOD_SET_APPROVAL_FOR_ALL || + txData.type === TRANSACTION_TYPES.TOKEN_METHOD_APPROVE; + + const isContractInteraction = + txData.type === TRANSACTION_TYPES.CONTRACT_INTERACTION; + const isContractInteractionFromDapp = - txData.type === TRANSACTION_TYPES.CONTRACT_INTERACTION && + (isTokenApproval || isContractInteraction) && txData.origin !== 'metamask'; let functionType; if (isContractInteractionFromDapp) { From e7e72cf6fcdace8a594e38721a5f03dc6ac7d1ac Mon Sep 17 00:00:00 2001 From: dragana8 <92531782+dragana8@users.noreply.github.com> Date: Fri, 16 Dec 2022 17:17:01 +0100 Subject: [PATCH 22/78] Fix insufficient currency buy or receive error message (#16979) --- ui/pages/send/gas-display/gas-display.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ui/pages/send/gas-display/gas-display.js b/ui/pages/send/gas-display/gas-display.js index 3bc48c6ee908..6f23f2abacae 100644 --- a/ui/pages/send/gas-display/gas-display.js +++ b/ui/pages/send/gas-display/gas-display.js @@ -79,6 +79,7 @@ export default function GasDisplay({ gasError }) { draftTransaction?.amount.error === INSUFFICIENT_TOKENS_ERROR; const editingTransaction = unapprovedTxs[draftTransaction.id]; const supportsEIP1559V2 = eip1559V2Enabled && supportsEIP1559; + const currentNetworkName = networkName || currentProvider.nickname; const transactionData = { txParams: { @@ -424,7 +425,7 @@ export default function GasDisplay({ gasError }) { ]} /> - {(gasError || isInsufficientTokenError) && ( + {(gasError || isInsufficientTokenError) && currentNetworkName && ( {t('insufficientCurrencyBuyOrReceive', [ nativeCurrency, - networkName ?? currentProvider.nickname, + currentNetworkName,
) : null} this.setState({ hasScrolledMessage: true })} setMessageRootRef={this.setMessageRootRef.bind(this)} messageRootRef={this.messageRootRef} diff --git a/ui/components/app/transaction-decoding/components/decoding/address/address.component.js b/ui/components/app/transaction-decoding/components/decoding/address/address.component.js index ddb4d5cd7598..9b576b5b3384 100644 --- a/ui/components/app/transaction-decoding/components/decoding/address/address.component.js +++ b/ui/components/app/transaction-decoding/components/decoding/address/address.component.js @@ -6,8 +6,8 @@ import { shortenAddress } from '../../../../../../helpers/utils/util'; import Identicon from '../../../../../ui/identicon'; import { useI18nContext } from '../../../../../../hooks/useI18nContext'; import { - getMetadataContractName, - getAddressBook, + getMemoizedMetadataContractName, + getMemoizedAddressBook, } from '../../../../../../selectors'; import NicknamePopovers from '../../../../modals/nickname-popovers'; @@ -21,14 +21,14 @@ const Address = ({ const t = useI18nContext(); const [showNicknamePopovers, setShowNicknamePopovers] = useState(false); - const addressBook = useSelector(getAddressBook); + const addressBook = useSelector(getMemoizedAddressBook); const addressBookEntryObject = addressBook.find( (entry) => entry.address.toLowerCase() === checksummedRecipientAddress.toLowerCase(), ); const recipientNickname = addressBookEntryObject?.name; const recipientMetadataName = useSelector((state) => - getMetadataContractName(state, checksummedRecipientAddress), + getMemoizedMetadataContractName(state, checksummedRecipientAddress), ); const recipientToRender = addressOnly diff --git a/ui/selectors/selectors.js b/ui/selectors/selectors.js index 7472ebc05ce6..53d2a4cfbd1d 100644 --- a/ui/selectors/selectors.js +++ b/ui/selectors/selectors.js @@ -814,6 +814,27 @@ export function getShowWhatsNewPopup(state) { const createDeepEqualSelector = createSelectorCreator(defaultMemoize, isEqual); +export const getMemoizedMetaMaskIdentities = createDeepEqualSelector( + getMetaMaskIdentities, + (identities) => identities, +); + +export const getMemoizedAddressBook = createDeepEqualSelector( + getAddressBook, + (addressBook) => addressBook, +); + +export const getMemoizedMetadataContractName = createDeepEqualSelector( + getTokenList, + (_tokenList, address) => address, + (tokenList, address) => { + const entry = Object.values(tokenList).find((identity) => + isEqualCaseInsensitive(identity.address, toChecksumHexAddress(address)), + ); + return entry && entry.name !== '' ? entry.name : ''; + }, +); + export const getUnapprovedTransactions = (state) => state.metamask.unapprovedTxs; From dd728b07db98e722aeb3e362bd1774ded1dcbde4 Mon Sep 17 00:00:00 2001 From: Vladimir Saric <92527393+VSaric@users.noreply.github.com> Date: Wed, 4 Jan 2023 18:01:52 +0100 Subject: [PATCH 30/78] Align custom spending cap Max button in approve screen for multiple languages (#16927) * Align custom spending cap Max button in approve screen for multiple languages * Modify some css styles and adding Box props * Using ButtonLink component instead of - { e.preventDefault(); setShowUseDefaultButton(false); @@ -184,12 +170,30 @@ export default function CustomSpendingCap({ }} > {t('useDefault')} - + ) } titleDetailWrapperProps={{ marginBottom: 2, marginRight: 0 }} allowDecimals /> + + { + e.preventDefault(); + handleChange(currentTokenBalance); + }} + > + {t('max')} + + - + From eb3aab4033725af0e547ba1de4977a77b7d7641c Mon Sep 17 00:00:00 2001 From: PeterYinusa Date: Thu, 5 Jan 2023 11:02:15 +0000 Subject: [PATCH 31/78] Merge remote-tracking branch 'origin/master' into Version-v10.24.0 --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 95acff6d0312..d0648fab856b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -71,6 +71,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [FLASK] Fix a crash that happens after snap install ([#16526](https://github.com/MetaMask/metamask-extension/pull/16526)) - [FLASK] Fix usage of wrong `ethereum` global for `ethereum` endowment ([#16932](https://github.com/MetaMask/metamask-extension/pull/16932)) +## [10.23.2] +### Fixed +- Improve performance on signature request screens ([#17052](https://github.com/MetaMask/metamask-extension/pull/17052)) + ## [10.23.1] ### Fixed - Fix incorrectly displaying "New Contract" instead of the recipient address, on the header from the Confirmation page ([#16961](https://github.com/MetaMask/metamask-extension/pull/16961)) @@ -3407,6 +3411,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [Unreleased]: https://github.com/MetaMask/metamask-extension/compare/v10.24.0...HEAD [10.24.0]: https://github.com/MetaMask/metamask-extension/compare/v10.23.1...v10.24.0 +[10.23.2]: https://github.com/MetaMask/metamask-extension/compare/v10.23.1...v10.23.2 [10.23.1]: https://github.com/MetaMask/metamask-extension/compare/v10.23.0...v10.23.1 [10.23.0]: https://github.com/MetaMask/metamask-extension/compare/v10.22.3...v10.23.0 [10.22.3]: https://github.com/MetaMask/metamask-extension/compare/v10.22.2...v10.22.3 From bd7c0a58aef87b3d357d6cdd68c0d11637a2b14f Mon Sep 17 00:00:00 2001 From: PeterYinusa Date: Thu, 5 Jan 2023 11:07:33 +0000 Subject: [PATCH 32/78] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d0648fab856b..e5383046461d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3410,7 +3410,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added the ability to restore accounts from seed words. [Unreleased]: https://github.com/MetaMask/metamask-extension/compare/v10.24.0...HEAD -[10.24.0]: https://github.com/MetaMask/metamask-extension/compare/v10.23.1...v10.24.0 +[10.24.0]: https://github.com/MetaMask/metamask-extension/compare/v10.23.2...v10.24.0 [10.23.2]: https://github.com/MetaMask/metamask-extension/compare/v10.23.1...v10.23.2 [10.23.1]: https://github.com/MetaMask/metamask-extension/compare/v10.23.0...v10.23.1 [10.23.0]: https://github.com/MetaMask/metamask-extension/compare/v10.22.3...v10.23.0 From e71b664bef9135dea8369186e4b8d338e3c55462 Mon Sep 17 00:00:00 2001 From: PeterYinusa Date: Thu, 5 Jan 2023 11:41:59 +0000 Subject: [PATCH 33/78] fix audit failure (#17079) --- .iyarc | 10 ++++++++++ lavamoat/browserify/beta/policy.json | 13 +------------ lavamoat/browserify/flask/policy.json | 13 +------------ lavamoat/browserify/main/policy.json | 13 +------------ package.json | 2 +- patches/fast-json-patch+2.2.1.patch | 13 ------------- yarn.lock | 7 ++++++- 7 files changed, 20 insertions(+), 51 deletions(-) delete mode 100644 patches/fast-json-patch+2.2.1.patch diff --git a/.iyarc b/.iyarc index 316510d7d26a..1d0f2111facf 100644 --- a/.iyarc +++ b/.iyarc @@ -1,2 +1,12 @@ # improved-yarn-audit advisory exclusions GHSA-257v-vj4p-3w2h + +# yarn npm audit reports on a fast-json-patch version < 3.1.1 but due to patch +# resolution, the only version of fast-json-patch that we use is 3.1.1. We also +# have 2.2.1 installed but it is a dev only dependency. The "violation" reports +# smart-transacton-controller as the culprit but if you run +# `yarn info -A -R dependents fast-json-patch` you can see that only 2.2.1 and +# 3.3.1 are installed and that smart-transaction-controller resolves to the +# patched version of 3.3.1. We can remove this once the +# smart-transaction-controller updates its dependency. +GHSA-8gh8-hqwg-xf34 diff --git a/lavamoat/browserify/beta/policy.json b/lavamoat/browserify/beta/policy.json index eb2708eafa1d..17ea352ad79e 100644 --- a/lavamoat/browserify/beta/policy.json +++ b/lavamoat/browserify/beta/policy.json @@ -1178,7 +1178,7 @@ "@metamask/controller-utils>isomorphic-fetch": true, "@metamask/smart-transactions-controller>@metamask/controllers": true, "@metamask/smart-transactions-controller>bignumber.js": true, - "@metamask/smart-transactions-controller>fast-json-patch": true, + "fast-json-patch": true, "lodash": true } }, @@ -1403,14 +1403,6 @@ "define": true } }, - "@metamask/smart-transactions-controller>fast-json-patch": { - "globals": { - "addEventListener": true, - "clearTimeout": true, - "removeEventListener": true, - "setTimeout": true - } - }, "@metamask/snaps-controllers>nanoid": { "globals": { "crypto.getRandomValues": true @@ -4597,9 +4589,6 @@ "clearTimeout": true, "removeEventListener": true, "setTimeout": true - }, - "packages": { - "fast-json-patch>fast-deep-equal": true } }, "fuse.js": { diff --git a/lavamoat/browserify/flask/policy.json b/lavamoat/browserify/flask/policy.json index bb0cbdf11390..87fc3e4af5bc 100644 --- a/lavamoat/browserify/flask/policy.json +++ b/lavamoat/browserify/flask/policy.json @@ -1440,7 +1440,7 @@ "@metamask/controller-utils>isomorphic-fetch": true, "@metamask/smart-transactions-controller>@metamask/controllers": true, "@metamask/smart-transactions-controller>bignumber.js": true, - "@metamask/smart-transactions-controller>fast-json-patch": true, + "fast-json-patch": true, "lodash": true } }, @@ -1665,14 +1665,6 @@ "define": true } }, - "@metamask/smart-transactions-controller>fast-json-patch": { - "globals": { - "addEventListener": true, - "clearTimeout": true, - "removeEventListener": true, - "setTimeout": true - } - }, "@metamask/snaps-controllers": { "globals": { "URL": true, @@ -5125,9 +5117,6 @@ "clearTimeout": true, "removeEventListener": true, "setTimeout": true - }, - "packages": { - "fast-json-patch>fast-deep-equal": true } }, "fuse.js": { diff --git a/lavamoat/browserify/main/policy.json b/lavamoat/browserify/main/policy.json index eb2708eafa1d..17ea352ad79e 100644 --- a/lavamoat/browserify/main/policy.json +++ b/lavamoat/browserify/main/policy.json @@ -1178,7 +1178,7 @@ "@metamask/controller-utils>isomorphic-fetch": true, "@metamask/smart-transactions-controller>@metamask/controllers": true, "@metamask/smart-transactions-controller>bignumber.js": true, - "@metamask/smart-transactions-controller>fast-json-patch": true, + "fast-json-patch": true, "lodash": true } }, @@ -1403,14 +1403,6 @@ "define": true } }, - "@metamask/smart-transactions-controller>fast-json-patch": { - "globals": { - "addEventListener": true, - "clearTimeout": true, - "removeEventListener": true, - "setTimeout": true - } - }, "@metamask/snaps-controllers>nanoid": { "globals": { "crypto.getRandomValues": true @@ -4597,9 +4589,6 @@ "clearTimeout": true, "removeEventListener": true, "setTimeout": true - }, - "packages": { - "fast-json-patch>fast-deep-equal": true } }, "fuse.js": { diff --git a/package.json b/package.json index 313b79874bc9..3ed1d685cdef 100644 --- a/package.json +++ b/package.json @@ -182,7 +182,7 @@ "ethjs-contract": "^0.2.3", "ethjs-query": "^0.3.4", "extension-port-stream": "^2.0.0", - "fast-json-patch": "^2.2.1", + "fast-json-patch": "^3.1.1", "fuse.js": "^3.2.0", "globalthis": "^1.0.1", "human-standard-token-abi": "^2.0.0", diff --git a/patches/fast-json-patch+2.2.1.patch b/patches/fast-json-patch+2.2.1.patch deleted file mode 100644 index d8f7b20f8bd7..000000000000 --- a/patches/fast-json-patch+2.2.1.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/node_modules/fast-json-patch/lib/helpers.js b/node_modules/fast-json-patch/lib/helpers.js -index 0ac28b4..d048c0a 100644 ---- a/node_modules/fast-json-patch/lib/helpers.js -+++ b/node_modules/fast-json-patch/lib/helpers.js -@@ -21,7 +21,7 @@ var _hasOwnProperty = Object.prototype.hasOwnProperty; - function hasOwnProperty(obj, key) { - return _hasOwnProperty.call(obj, key); - } --exports.hasOwnProperty = hasOwnProperty; -+Object.defineProperty(exports, "hasOwnProperty", { value: hasOwnProperty }); - function _objectKeys(obj) { - if (Array.isArray(obj)) { - var keys = new Array(obj.length); \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 7402c3793cd4..66d44a927bbc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12356,7 +12356,7 @@ fast-json-parse@^1.0.3: resolved "https://registry.yarnpkg.com/fast-json-parse/-/fast-json-parse-1.0.3.tgz#43e5c61ee4efa9265633046b770fb682a7577c4d" integrity sha512-FRWsaZRWEJ1ESVNbDWmsAlqDk96gPQezzLghafp5J4GUKjbCz3OkAHuZs5TuPEtkbVQERysLp9xv6c24fBm8Aw== -fast-json-patch@^2.0.6, fast-json-patch@^2.2.1: +fast-json-patch@^2.0.6: version "2.2.1" resolved "https://registry.yarnpkg.com/fast-json-patch/-/fast-json-patch-2.2.1.tgz#18150d36c9ab65c7209e7d4eb113f4f8eaabe6d9" integrity sha512-4j5uBaTnsYAV5ebkidvxiLUYOwjQ+JSFljeqfTxCrH9bDmlCQaOJFS84oDJ2rAXZq2yskmk3ORfoP9DCwqFNig== @@ -12368,6 +12368,11 @@ fast-json-patch@^3.1.0: resolved "https://registry.yarnpkg.com/fast-json-patch/-/fast-json-patch-3.1.0.tgz#ec8cd9b9c4c564250ec8b9140ef7a55f70acaee6" integrity sha512-IhpytlsVTRndz0hU5t0/MGzS/etxLlfrpG5V5M9mVbuj9TrJLWaMfsox9REM5rkuGX0T+5qjpe8XA1o0gZ42nA== +fast-json-patch@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/fast-json-patch/-/fast-json-patch-3.1.1.tgz#85064ea1b1ebf97a3f7ad01e23f9337e72c66947" + integrity sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ== + fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" From 94b0d7fb9148c4aef942f99f9c30a3a707675dd5 Mon Sep 17 00:00:00 2001 From: PeterYinusa Date: Thu, 5 Jan 2023 20:27:06 +0000 Subject: [PATCH 34/78] Update policies --- lavamoat/browserify/beta/policy.json | 10 +++++++++- lavamoat/browserify/flask/policy.json | 10 +++++++++- lavamoat/browserify/main/policy.json | 10 +++++++++- ...sactions-controller++fast-json-patch+3.1.0.patch | 13 ------------- patches/fast-json-patch+3.1.1.patch | 13 +++++++++++++ yarn.lock | 7 +------ 6 files changed, 41 insertions(+), 22 deletions(-) delete mode 100644 patches/@metamask+smart-transactions-controller++fast-json-patch+3.1.0.patch create mode 100644 patches/fast-json-patch+3.1.1.patch diff --git a/lavamoat/browserify/beta/policy.json b/lavamoat/browserify/beta/policy.json index 17ea352ad79e..2b5f33acded5 100644 --- a/lavamoat/browserify/beta/policy.json +++ b/lavamoat/browserify/beta/policy.json @@ -1178,7 +1178,7 @@ "@metamask/controller-utils>isomorphic-fetch": true, "@metamask/smart-transactions-controller>@metamask/controllers": true, "@metamask/smart-transactions-controller>bignumber.js": true, - "fast-json-patch": true, + "@metamask/smart-transactions-controller>fast-json-patch": true, "lodash": true } }, @@ -1403,6 +1403,14 @@ "define": true } }, + "@metamask/smart-transactions-controller>fast-json-patch": { + "globals": { + "addEventListener": true, + "clearTimeout": true, + "removeEventListener": true, + "setTimeout": true + } + }, "@metamask/snaps-controllers>nanoid": { "globals": { "crypto.getRandomValues": true diff --git a/lavamoat/browserify/flask/policy.json b/lavamoat/browserify/flask/policy.json index 87fc3e4af5bc..59c0013f199b 100644 --- a/lavamoat/browserify/flask/policy.json +++ b/lavamoat/browserify/flask/policy.json @@ -1440,7 +1440,7 @@ "@metamask/controller-utils>isomorphic-fetch": true, "@metamask/smart-transactions-controller>@metamask/controllers": true, "@metamask/smart-transactions-controller>bignumber.js": true, - "fast-json-patch": true, + "@metamask/smart-transactions-controller>fast-json-patch": true, "lodash": true } }, @@ -1665,6 +1665,14 @@ "define": true } }, + "@metamask/smart-transactions-controller>fast-json-patch": { + "globals": { + "addEventListener": true, + "clearTimeout": true, + "removeEventListener": true, + "setTimeout": true + } + }, "@metamask/snaps-controllers": { "globals": { "URL": true, diff --git a/lavamoat/browserify/main/policy.json b/lavamoat/browserify/main/policy.json index 17ea352ad79e..2b5f33acded5 100644 --- a/lavamoat/browserify/main/policy.json +++ b/lavamoat/browserify/main/policy.json @@ -1178,7 +1178,7 @@ "@metamask/controller-utils>isomorphic-fetch": true, "@metamask/smart-transactions-controller>@metamask/controllers": true, "@metamask/smart-transactions-controller>bignumber.js": true, - "fast-json-patch": true, + "@metamask/smart-transactions-controller>fast-json-patch": true, "lodash": true } }, @@ -1403,6 +1403,14 @@ "define": true } }, + "@metamask/smart-transactions-controller>fast-json-patch": { + "globals": { + "addEventListener": true, + "clearTimeout": true, + "removeEventListener": true, + "setTimeout": true + } + }, "@metamask/snaps-controllers>nanoid": { "globals": { "crypto.getRandomValues": true diff --git a/patches/@metamask+smart-transactions-controller++fast-json-patch+3.1.0.patch b/patches/@metamask+smart-transactions-controller++fast-json-patch+3.1.0.patch deleted file mode 100644 index 97762d5a9ef8..000000000000 --- a/patches/@metamask+smart-transactions-controller++fast-json-patch+3.1.0.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/node_modules/@metamask/smart-transactions-controller/node_modules/fast-json-patch/commonjs/helpers.js b/node_modules/@metamask/smart-transactions-controller/node_modules/fast-json-patch/commonjs/helpers.js -index 0ac28b4..d048c0a 100644 ---- a/node_modules/@metamask/smart-transactions-controller/node_modules/fast-json-patch/commonjs/helpers.js -+++ b/node_modules/@metamask/smart-transactions-controller/node_modules/fast-json-patch/commonjs/helpers.js -@@ -21,7 +21,7 @@ var _hasOwnProperty = Object.prototype.hasOwnProperty; - function hasOwnProperty(obj, key) { - return _hasOwnProperty.call(obj, key); - } --exports.hasOwnProperty = hasOwnProperty; -+Object.defineProperty(exports, "hasOwnProperty", { value: hasOwnProperty }); - function _objectKeys(obj) { - if (Array.isArray(obj)) { - var keys = new Array(obj.length); diff --git a/patches/fast-json-patch+3.1.1.patch b/patches/fast-json-patch+3.1.1.patch new file mode 100644 index 000000000000..9a481f0cd55f --- /dev/null +++ b/patches/fast-json-patch+3.1.1.patch @@ -0,0 +1,13 @@ +diff --git a/node_modules/fast-json-patch/commonjs/helpers.js b/node_modules/fast-json-patch/commonjs/helpers.js +index 5f2350e..8894686 100644 +--- a/node_modules/fast-json-patch/commonjs/helpers.js ++++ b/node_modules/fast-json-patch/commonjs/helpers.js +@@ -21,7 +21,7 @@ var _hasOwnProperty = Object.prototype.hasOwnProperty; + function hasOwnProperty(obj, key) { + return _hasOwnProperty.call(obj, key); + } +-exports.hasOwnProperty = hasOwnProperty; ++Object.defineProperty(exports, "hasOwnProperty", { value: hasOwnProperty }); + function _objectKeys(obj) { + if (Array.isArray(obj)) { + var keys_1 = new Array(obj.length); diff --git a/yarn.lock b/yarn.lock index 66d44a927bbc..f10179de912e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12363,12 +12363,7 @@ fast-json-patch@^2.0.6: dependencies: fast-deep-equal "^2.0.1" -fast-json-patch@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/fast-json-patch/-/fast-json-patch-3.1.0.tgz#ec8cd9b9c4c564250ec8b9140ef7a55f70acaee6" - integrity sha512-IhpytlsVTRndz0hU5t0/MGzS/etxLlfrpG5V5M9mVbuj9TrJLWaMfsox9REM5rkuGX0T+5qjpe8XA1o0gZ42nA== - -fast-json-patch@^3.1.1: +fast-json-patch@^3.1.0, fast-json-patch@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/fast-json-patch/-/fast-json-patch-3.1.1.tgz#85064ea1b1ebf97a3f7ad01e23f9337e72c66947" integrity sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ== From cae0fcf17be7a03e7d69d0e8aa9030f831cd3b78 Mon Sep 17 00:00:00 2001 From: PeterYinusa Date: Mon, 9 Jan 2023 13:47:24 +0000 Subject: [PATCH 35/78] policy updates --- lavamoat/browserify/beta/policy.json | 10 +--------- lavamoat/browserify/flask/policy.json | 10 +--------- lavamoat/browserify/main/policy.json | 10 +--------- 3 files changed, 3 insertions(+), 27 deletions(-) diff --git a/lavamoat/browserify/beta/policy.json b/lavamoat/browserify/beta/policy.json index 2b5f33acded5..17ea352ad79e 100644 --- a/lavamoat/browserify/beta/policy.json +++ b/lavamoat/browserify/beta/policy.json @@ -1178,7 +1178,7 @@ "@metamask/controller-utils>isomorphic-fetch": true, "@metamask/smart-transactions-controller>@metamask/controllers": true, "@metamask/smart-transactions-controller>bignumber.js": true, - "@metamask/smart-transactions-controller>fast-json-patch": true, + "fast-json-patch": true, "lodash": true } }, @@ -1403,14 +1403,6 @@ "define": true } }, - "@metamask/smart-transactions-controller>fast-json-patch": { - "globals": { - "addEventListener": true, - "clearTimeout": true, - "removeEventListener": true, - "setTimeout": true - } - }, "@metamask/snaps-controllers>nanoid": { "globals": { "crypto.getRandomValues": true diff --git a/lavamoat/browserify/flask/policy.json b/lavamoat/browserify/flask/policy.json index 59c0013f199b..87fc3e4af5bc 100644 --- a/lavamoat/browserify/flask/policy.json +++ b/lavamoat/browserify/flask/policy.json @@ -1440,7 +1440,7 @@ "@metamask/controller-utils>isomorphic-fetch": true, "@metamask/smart-transactions-controller>@metamask/controllers": true, "@metamask/smart-transactions-controller>bignumber.js": true, - "@metamask/smart-transactions-controller>fast-json-patch": true, + "fast-json-patch": true, "lodash": true } }, @@ -1665,14 +1665,6 @@ "define": true } }, - "@metamask/smart-transactions-controller>fast-json-patch": { - "globals": { - "addEventListener": true, - "clearTimeout": true, - "removeEventListener": true, - "setTimeout": true - } - }, "@metamask/snaps-controllers": { "globals": { "URL": true, diff --git a/lavamoat/browserify/main/policy.json b/lavamoat/browserify/main/policy.json index 2b5f33acded5..17ea352ad79e 100644 --- a/lavamoat/browserify/main/policy.json +++ b/lavamoat/browserify/main/policy.json @@ -1178,7 +1178,7 @@ "@metamask/controller-utils>isomorphic-fetch": true, "@metamask/smart-transactions-controller>@metamask/controllers": true, "@metamask/smart-transactions-controller>bignumber.js": true, - "@metamask/smart-transactions-controller>fast-json-patch": true, + "fast-json-patch": true, "lodash": true } }, @@ -1403,14 +1403,6 @@ "define": true } }, - "@metamask/smart-transactions-controller>fast-json-patch": { - "globals": { - "addEventListener": true, - "clearTimeout": true, - "removeEventListener": true, - "setTimeout": true - } - }, "@metamask/snaps-controllers>nanoid": { "globals": { "crypto.getRandomValues": true From 2f7b63e9f485dc433362e7df92673e4eb7041739 Mon Sep 17 00:00:00 2001 From: PeterYinusa Date: Mon, 9 Jan 2023 14:24:50 +0000 Subject: [PATCH 36/78] Remove fast-json-patch exclusion --- .iyarc | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/.iyarc b/.iyarc index 1d0f2111facf..316510d7d26a 100644 --- a/.iyarc +++ b/.iyarc @@ -1,12 +1,2 @@ # improved-yarn-audit advisory exclusions GHSA-257v-vj4p-3w2h - -# yarn npm audit reports on a fast-json-patch version < 3.1.1 but due to patch -# resolution, the only version of fast-json-patch that we use is 3.1.1. We also -# have 2.2.1 installed but it is a dev only dependency. The "violation" reports -# smart-transacton-controller as the culprit but if you run -# `yarn info -A -R dependents fast-json-patch` you can see that only 2.2.1 and -# 3.3.1 are installed and that smart-transaction-controller resolves to the -# patched version of 3.3.1. We can remove this once the -# smart-transaction-controller updates its dependency. -GHSA-8gh8-hqwg-xf34 From c33b0a83a9e4ec5e6baeedc19c69d0bd344693cf Mon Sep 17 00:00:00 2001 From: seaona Date: Mon, 9 Jan 2023 16:24:50 +0100 Subject: [PATCH 37/78] run lavamoat:auto --- lavamoat/build-system/policy.json | 1499 +++++++---------------------- 1 file changed, 362 insertions(+), 1137 deletions(-) diff --git a/lavamoat/build-system/policy.json b/lavamoat/build-system/policy.json index b8156a01c760..c0e418279b5e 100644 --- a/lavamoat/build-system/policy.json +++ b/lavamoat/build-system/policy.json @@ -1800,7 +1800,6 @@ }, "packages": { "chokidar>braces": true, - "chokidar>fsevents": true, "chokidar>glob-parent": true, "chokidar>is-binary-path": true, "chokidar>normalize-path": true, @@ -1827,12 +1826,6 @@ "chokidar>braces>fill-range>to-regex-range>is-number": true } }, - "chokidar>fsevents": { - "globals": { - "process.platform": true - }, - "native": true - }, "chokidar>glob-parent": { "builtin": { "os.platform": true, @@ -4163,7 +4156,6 @@ "gulp-watch>chokidar>anymatch": true, "gulp-watch>chokidar>async-each": true, "gulp-watch>chokidar>braces": true, - "gulp-watch>chokidar>fsevents": true, "gulp-watch>chokidar>is-binary-path": true, "gulp-watch>chokidar>normalize-path": true, "gulp-watch>chokidar>readdirp": true, @@ -4628,413 +4620,403 @@ "enzyme>rst-selector-parser>nearley>randexp>ret": true } }, - "gulp-watch>chokidar>fsevents": { + "gulp-watch>chokidar>is-binary-path": { "builtin": { - "events.EventEmitter": true, - "fs.stat": true, - "path.join": true, - "util.inherits": true - }, - "globals": { - "__dirname": true, - "process.nextTick": true, - "process.platform": true, - "setImmediate": true + "path.extname": true }, "packages": { - "gulp-watch>chokidar>fsevents>node-pre-gyp": true + "gulp-watch>chokidar>is-binary-path>binary-extensions": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp": { + "gulp-watch>chokidar>readdirp": { "builtin": { - "events.EventEmitter": true, - "fs.existsSync": true, - "fs.readFileSync": true, - "fs.renameSync": true, - "path.dirname": true, - "path.existsSync": true, "path.join": true, - "path.resolve": true, - "url.parse": true, - "url.resolve": true, + "path.relative": true, "util.inherits": true }, "globals": { - "__dirname": true, - "console.log": true, - "process.arch": true, - "process.cwd": true, - "process.env": true, - "process.platform": true, - "process.version.substr": true, - "process.versions": true + "setImmediate": true }, "packages": { - "gulp-watch>chokidar>fsevents>node-pre-gyp>detect-libc": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>nopt": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>semver": true - } - }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>detect-libc": { - "builtin": { - "child_process.spawnSync": true, - "fs.readdirSync": true, - "os.platform": true - }, - "globals": { - "process.env": true + "gulp-watch>chokidar>readdirp>micromatch": true, + "readable-stream": true, + "webpack>graceful-fs": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>nopt": { + "gulp-watch>chokidar>readdirp>micromatch": { "builtin": { - "path": true, - "stream.Stream": true, - "url": true + "path.basename": true, + "path.sep": true, + "util.inspect": true }, "globals": { - "console": true, - "process.argv": true, - "process.env.DEBUG_NOPT": true, - "process.env.NOPT_DEBUG": true, "process.platform": true }, "packages": { - "gulp-watch>chokidar>fsevents>node-pre-gyp>nopt>abbrev": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>nopt>osenv": true + "gulp-watch>chokidar>braces": true, + "gulp-watch>chokidar>braces>snapdragon": true, + "gulp-watch>chokidar>braces>to-regex": true, + "gulp-watch>chokidar>readdirp>micromatch>arr-diff": true, + "gulp-watch>chokidar>readdirp>micromatch>array-unique": true, + "gulp-watch>chokidar>readdirp>micromatch>define-property": true, + "gulp-watch>chokidar>readdirp>micromatch>extend-shallow": true, + "gulp-watch>chokidar>readdirp>micromatch>extglob": true, + "gulp-watch>chokidar>readdirp>micromatch>kind-of": true, + "gulp>gulp-cli>liftoff>fined>object.pick": true, + "gulp>gulp-cli>matchdep>micromatch>fragment-cache": true, + "gulp>gulp-cli>matchdep>micromatch>nanomatch": true, + "gulp>gulp-cli>matchdep>micromatch>regex-not": true + } + }, + "gulp-watch>chokidar>readdirp>micromatch>define-property": { + "packages": { + "gulp>gulp-cli>isobject": true, + "gulp>gulp-cli>matchdep>micromatch>define-property>is-descriptor": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>nopt>osenv": { - "builtin": { - "child_process.exec": true, - "path": true - }, - "globals": { - "process.env.COMPUTERNAME": true, - "process.env.ComSpec": true, - "process.env.EDITOR": true, - "process.env.HOSTNAME": true, - "process.env.PATH": true, - "process.env.PROMPT": true, - "process.env.PS1": true, - "process.env.Path": true, - "process.env.SHELL": true, - "process.env.USER": true, - "process.env.USERDOMAIN": true, - "process.env.USERNAME": true, - "process.env.VISUAL": true, - "process.env.path": true, - "process.nextTick": true, - "process.platform": true - }, + "gulp-watch>chokidar>readdirp>micromatch>extend-shallow": { "packages": { - "gulp-watch>chokidar>fsevents>node-pre-gyp>nopt>osenv>os-homedir": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>nopt>osenv>os-tmpdir": true + "gulp-watch>chokidar>readdirp>micromatch>extend-shallow>is-extendable": true, + "gulp-zip>plugin-error>extend-shallow>assign-symbols": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>nopt>osenv>os-homedir": { - "builtin": { - "os.homedir": true - }, - "globals": { - "process.env": true, - "process.getuid": true, - "process.platform": true + "gulp-watch>chokidar>readdirp>micromatch>extend-shallow>is-extendable": { + "packages": { + "@babel/register>clone-deep>is-plain-object": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>nopt>osenv>os-tmpdir": { - "globals": { - "process.env.SystemRoot": true, - "process.env.TEMP": true, - "process.env.TMP": true, - "process.env.TMPDIR": true, - "process.env.windir": true, - "process.platform": true + "gulp-watch>chokidar>readdirp>micromatch>extglob": { + "packages": { + "gulp-watch>chokidar>braces>snapdragon": true, + "gulp-watch>chokidar>braces>to-regex": true, + "gulp-watch>chokidar>readdirp>micromatch>array-unique": true, + "gulp-watch>chokidar>readdirp>micromatch>extglob>define-property": true, + "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets": true, + "gulp-watch>chokidar>readdirp>micromatch>extglob>extend-shallow": true, + "gulp>gulp-cli>matchdep>micromatch>fragment-cache": true, + "gulp>gulp-cli>matchdep>micromatch>regex-not": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog": { - "builtin": { - "events.EventEmitter": true, - "util": true - }, - "globals": { - "process.nextTick": true, - "process.stderr": true - }, + "gulp-watch>chokidar>readdirp>micromatch>extglob>define-property": { "packages": { - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>console-control-strings": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>gauge": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>set-blocking": true + "gulp>gulp-cli>matchdep>micromatch>define-property>is-descriptor": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet": { - "builtin": { - "events.EventEmitter": true, - "util.inherits": true + "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets": { + "globals": { + "__filename": true }, "packages": { - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet>delegates": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet>readable-stream": true + "gulp-watch>chokidar>braces>snapdragon": true, + "gulp-watch>chokidar>braces>to-regex": true, + "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>debug": true, + "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>define-property": true, + "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>extend-shallow": true, + "gulp>gulp-cli>matchdep>micromatch>extglob>expand-brackets>posix-character-classes": true, + "gulp>gulp-cli>matchdep>micromatch>regex-not": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet>readable-stream": { + "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>debug": { "builtin": { - "events.EventEmitter": true, - "stream": true, + "fs.SyncWriteStream": true, + "net.Socket": true, + "tty.WriteStream": true, + "tty.isatty": true, "util": true }, "globals": { - "process.browser": true, - "process.env.READABLE_STREAM": true, - "process.stderr": true, - "process.stdout": true, - "process.version.slice": true, - "setImmediate": true + "chrome": true, + "console": true, + "document": true, + "localStorage": true, + "navigator": true, + "process": true }, "packages": { - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet>readable-stream>core-util-is": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet>readable-stream>isarray": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet>readable-stream>process-nextick-args": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet>readable-stream>string_decoder": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet>readable-stream>util-deprecate": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf>glob>inherits": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>tar>safe-buffer": true + "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>debug>ms": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet>readable-stream>core-util-is": { - "globals": { - "Buffer.isBuffer": true + "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>define-property": { + "packages": { + "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>define-property>is-descriptor": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet>readable-stream>process-nextick-args": { - "globals": { - "process": true + "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>define-property>is-descriptor": { + "packages": { + "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-accessor-descriptor": true, + "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-data-descriptor": true, + "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>define-property>is-descriptor>kind-of": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet>readable-stream>string_decoder": { + "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-accessor-descriptor": { "packages": { - "gulp-watch>chokidar>fsevents>node-pre-gyp>tar>safe-buffer": true + "gulp-watch>anymatch>micromatch>kind-of": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet>readable-stream>util-deprecate": { - "builtin": { - "util.deprecate": true + "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-data-descriptor": { + "packages": { + "gulp-watch>anymatch>micromatch>kind-of": true + } + }, + "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>extend-shallow": { + "packages": { + "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>extend-shallow>is-extendable": true + } + }, + "gulp-watch>chokidar>readdirp>micromatch>extglob>extend-shallow": { + "packages": { + "gulp-watch>chokidar>readdirp>micromatch>extglob>extend-shallow>is-extendable": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>gauge": { + "gulp-watch>chokidar>upath": { "builtin": { - "util.format": true - }, + "path": true + } + }, + "gulp-watch>fancy-log": { "globals": { - "clearInterval": true, - "process": true, - "setImmediate": true, - "setInterval": true + "console": true, + "process.argv.indexOf": true, + "process.stderr.write": true, + "process.stdout.write": true }, "packages": { - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>console-control-strings": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>gauge>aproba": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>gauge>has-unicode": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>gauge>object-assign": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>gauge>signal-exit": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>gauge>string-width": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>gauge>strip-ansi": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>gauge>wide-align": true + "fancy-log>ansi-gray": true, + "fancy-log>color-support": true, + "fancy-log>time-stamp": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>gauge>has-unicode": { + "gulp-watch>glob-parent": { "builtin": { - "os.type": true + "os.platform": true, + "path": true }, - "globals": { - "process.env.LANG": true, - "process.env.LC_ALL": true, - "process.env.LC_CTYPE": true + "packages": { + "gulp-watch>glob-parent>is-glob": true, + "gulp-watch>glob-parent>path-dirname": true + } + }, + "gulp-watch>glob-parent>is-glob": { + "packages": { + "gulp-watch>glob-parent>is-glob>is-extglob": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>gauge>signal-exit": { + "gulp-watch>glob-parent>path-dirname": { "builtin": { - "assert.equal": true, - "events": true + "path": true, + "util.inspect": true }, "globals": { - "process": true + "process.platform": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>gauge>string-width": { - "packages": { - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>gauge>string-width>code-point-at": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>gauge>string-width>is-fullwidth-code-point": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>gauge>strip-ansi": true + "gulp-watch>path-is-absolute": { + "globals": { + "process.platform": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>gauge>string-width>is-fullwidth-code-point": { + "gulp-watch>vinyl-file": { + "builtin": { + "path.resolve": true + }, + "globals": { + "process.cwd": true + }, "packages": { - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>gauge>string-width>is-fullwidth-code-point>number-is-nan": true + "del>globby>pinkie-promise": true, + "gulp-watch>vinyl-file>pify": true, + "gulp-watch>vinyl-file>strip-bom": true, + "gulp-watch>vinyl-file>strip-bom-stream": true, + "gulp-watch>vinyl-file>vinyl": true, + "webpack>graceful-fs": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>gauge>strip-ansi": { + "gulp-watch>vinyl-file>strip-bom": { + "globals": { + "Buffer.isBuffer": true + }, "packages": { - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>gauge>strip-ansi>ansi-regex": true + "gulp>vinyl-fs>remove-bom-buffer>is-utf8": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>gauge>wide-align": { + "gulp-watch>vinyl-file>strip-bom-stream": { "packages": { - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>gauge>string-width": true - } - }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>npmlog>set-blocking": { - "globals": { - "process.stderr": true, - "process.stdout": true + "gulp-watch>vinyl-file>strip-bom": true, + "gulp-watch>vinyl-file>strip-bom-stream>first-chunk-stream": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf": { + "gulp-watch>vinyl-file>strip-bom-stream>first-chunk-stream": { "builtin": { - "assert": true, - "fs": true, - "path.join": true + "util.inherits": true }, "globals": { - "process.platform": true, - "setTimeout": true + "Buffer.concat": true, + "setImmediate": true }, "packages": { - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf>glob": true + "readable-stream": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf>glob": { + "gulp-watch>vinyl-file>vinyl": { "builtin": { - "assert": true, - "events.EventEmitter": true, - "fs.lstat": true, - "fs.lstatSync": true, - "fs.readdir": true, - "fs.readdirSync": true, - "fs.stat": true, - "fs.statSync": true, + "buffer.Buffer": true, + "path.basename": true, + "path.dirname": true, + "path.extname": true, "path.join": true, - "path.resolve": true, - "util": true + "path.relative": true, + "stream.PassThrough": true, + "stream.Stream": true }, "globals": { - "console.error": true, - "process.cwd": true, - "process.nextTick": true, - "process.platform": true + "process.cwd": true }, "packages": { - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf>glob>fs.realpath": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf>glob>inflight": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf>glob>inherits": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf>glob>minimatch": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf>glob>once": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf>glob>path-is-absolute": true + "gulp-watch>vinyl-file>vinyl>clone": true, + "gulp-watch>vinyl-file>vinyl>clone-stats": true, + "gulp-watch>vinyl-file>vinyl>replace-ext": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf>glob>fs.realpath": { - "builtin": { - "fs.lstat": true, - "fs.lstatSync": true, - "fs.readlink": true, - "fs.readlinkSync": true, - "fs.realpath": true, - "fs.realpathSync": true, - "fs.stat": true, - "fs.statSync": true, - "path.normalize": true, - "path.resolve": true - }, + "gulp-watch>vinyl-file>vinyl>clone": { "globals": { - "console.error": true, - "console.trace": true, - "process.env.NODE_DEBUG": true, - "process.nextTick": true, - "process.noDeprecation": true, - "process.platform": true, - "process.throwDeprecation": true, - "process.traceDeprecation": true, - "process.version": true + "Buffer": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf>glob>inflight": { - "globals": { - "process.nextTick": true - }, - "packages": { - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf>glob>once": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf>glob>once>wrappy": true + "gulp-watch>vinyl-file>vinyl>clone-stats": { + "builtin": { + "fs.Stats": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf>glob>inherits": { + "gulp-watch>vinyl-file>vinyl>replace-ext": { "builtin": { - "util.inherits": true + "path.basename": true, + "path.dirname": true, + "path.extname": true, + "path.join": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf>glob>minimatch": { + "gulp-zip": { "builtin": { - "path": true + "buffer.constants.MAX_LENGTH": true, + "path.join": true + }, + "packages": { + "gulp-zip>get-stream": true, + "gulp-zip>plugin-error": true, + "gulp-zip>through2": true, + "gulp-zip>yazl": true, + "vinyl": true + } + }, + "gulp-zip>get-stream": { + "builtin": { + "buffer.constants.MAX_LENGTH": true, + "stream.PassThrough": true }, "globals": { - "console.error": true + "Buffer.concat": true }, "packages": { - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf>glob>minimatch>brace-expansion": true + "pump": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf>glob>minimatch>brace-expansion": { + "gulp-zip>plugin-error": { + "builtin": { + "util.inherits": true + }, "packages": { - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf>glob>minimatch>brace-expansion>balanced-match": true, - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf>glob>minimatch>brace-expansion>concat-map": true + "gulp-watch>ansi-colors": true, + "gulp-zip>plugin-error>arr-diff": true, + "gulp-zip>plugin-error>arr-union": true, + "gulp-zip>plugin-error>extend-shallow": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf>glob>once": { + "gulp-zip>plugin-error>extend-shallow": { "packages": { - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf>glob>once>wrappy": true + "gulp-zip>plugin-error>extend-shallow>assign-symbols": true, + "gulp-zip>plugin-error>extend-shallow>is-extendable": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>rimraf>glob>path-is-absolute": { - "globals": { - "process.platform": true + "gulp-zip>plugin-error>extend-shallow>is-extendable": { + "packages": { + "@babel/register>clone-deep>is-plain-object": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>semver": { + "gulp-zip>through2": { + "builtin": { + "util.inherits": true + }, "globals": { - "console": true, - "process": true + "process.nextTick": true + }, + "packages": { + "gulp-zip>through2>readable-stream": true } }, - "gulp-watch>chokidar>fsevents>node-pre-gyp>tar>safe-buffer": { + "gulp-zip>through2>readable-stream": { "builtin": { - "buffer": true + "buffer.Buffer": true, + "events.EventEmitter": true, + "stream": true, + "util": true + }, + "globals": { + "process.env.READABLE_STREAM": true, + "process.nextTick": true, + "process.stderr": true, + "process.stdout": true + }, + "packages": { + "@storybook/api>util-deprecate": true, + "browserify>string_decoder": true, + "pumpify>inherits": true } }, - "gulp-watch>chokidar>is-binary-path": { + "gulp-zip>yazl": { "builtin": { - "path.extname": true + "events.EventEmitter": true, + "fs.createReadStream": true, + "fs.stat": true, + "stream.PassThrough": true, + "stream.Transform": true, + "util.inherits": true, + "zlib.DeflateRaw": true, + "zlib.deflateRaw": true + }, + "globals": { + "Buffer": true, + "setImmediate": true, + "utf8FileName.length": true }, "packages": { - "gulp-watch>chokidar>is-binary-path>binary-extensions": true + "gulp-zip>yazl>buffer-crc32": true } }, - "gulp-watch>chokidar>readdirp": { + "gulp-zip>yazl>buffer-crc32": { "builtin": { - "path.join": true, - "path.relative": true, - "util.inherits": true - }, - "globals": { - "setImmediate": true + "buffer.Buffer": true + } + }, + "gulp>glob-watcher": { + "packages": { + "gulp>glob-watcher>anymatch": true, + "gulp>glob-watcher>async-done": true, + "gulp>glob-watcher>chokidar": true, + "gulp>glob-watcher>is-negated-glob": true, + "gulp>glob-watcher>just-debounce": true, + "gulp>undertaker>object.defaults": true + } + }, + "gulp>glob-watcher>anymatch": { + "builtin": { + "path.sep": true }, "packages": { - "gulp-watch>chokidar>readdirp>micromatch": true, - "readable-stream": true, - "webpack>graceful-fs": true + "gulp>glob-watcher>anymatch>micromatch": true, + "gulp>glob-watcher>anymatch>normalize-path": true } }, - "gulp-watch>chokidar>readdirp>micromatch": { + "gulp>glob-watcher>anymatch>micromatch": { "builtin": { "path.basename": true, "path.sep": true, @@ -5044,70 +5026,70 @@ "process.platform": true }, "packages": { - "gulp-watch>chokidar>braces": true, + "@babel/register>clone-deep>kind-of": true, "gulp-watch>chokidar>braces>snapdragon": true, "gulp-watch>chokidar>braces>to-regex": true, - "gulp-watch>chokidar>readdirp>micromatch>arr-diff": true, - "gulp-watch>chokidar>readdirp>micromatch>array-unique": true, - "gulp-watch>chokidar>readdirp>micromatch>define-property": true, - "gulp-watch>chokidar>readdirp>micromatch>extend-shallow": true, - "gulp-watch>chokidar>readdirp>micromatch>extglob": true, - "gulp-watch>chokidar>readdirp>micromatch>kind-of": true, + "gulp-zip>plugin-error>arr-diff": true, + "gulp>glob-watcher>anymatch>micromatch>define-property": true, + "gulp>glob-watcher>anymatch>micromatch>extend-shallow": true, + "gulp>glob-watcher>anymatch>micromatch>extglob": true, + "gulp>glob-watcher>chokidar>braces": true, "gulp>gulp-cli>liftoff>fined>object.pick": true, + "gulp>gulp-cli>matchdep>micromatch>array-unique": true, "gulp>gulp-cli>matchdep>micromatch>fragment-cache": true, "gulp>gulp-cli>matchdep>micromatch>nanomatch": true, "gulp>gulp-cli>matchdep>micromatch>regex-not": true } }, - "gulp-watch>chokidar>readdirp>micromatch>define-property": { + "gulp>glob-watcher>anymatch>micromatch>define-property": { "packages": { "gulp>gulp-cli>isobject": true, "gulp>gulp-cli>matchdep>micromatch>define-property>is-descriptor": true } }, - "gulp-watch>chokidar>readdirp>micromatch>extend-shallow": { + "gulp>glob-watcher>anymatch>micromatch>extend-shallow": { "packages": { - "gulp-watch>chokidar>readdirp>micromatch>extend-shallow>is-extendable": true, - "gulp-zip>plugin-error>extend-shallow>assign-symbols": true + "gulp-zip>plugin-error>extend-shallow>assign-symbols": true, + "gulp>glob-watcher>anymatch>micromatch>extend-shallow>is-extendable": true } }, - "gulp-watch>chokidar>readdirp>micromatch>extend-shallow>is-extendable": { + "gulp>glob-watcher>anymatch>micromatch>extend-shallow>is-extendable": { "packages": { "@babel/register>clone-deep>is-plain-object": true } }, - "gulp-watch>chokidar>readdirp>micromatch>extglob": { + "gulp>glob-watcher>anymatch>micromatch>extglob": { "packages": { + "gulp-watch>chokidar>braces>extend-shallow": true, "gulp-watch>chokidar>braces>snapdragon": true, "gulp-watch>chokidar>braces>to-regex": true, - "gulp-watch>chokidar>readdirp>micromatch>array-unique": true, - "gulp-watch>chokidar>readdirp>micromatch>extglob>define-property": true, - "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets": true, - "gulp-watch>chokidar>readdirp>micromatch>extglob>extend-shallow": true, + "gulp>glob-watcher>anymatch>micromatch>extglob>define-property": true, + "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets": true, + "gulp>gulp-cli>matchdep>micromatch>array-unique": true, "gulp>gulp-cli>matchdep>micromatch>fragment-cache": true, "gulp>gulp-cli>matchdep>micromatch>regex-not": true } }, - "gulp-watch>chokidar>readdirp>micromatch>extglob>define-property": { + "gulp>glob-watcher>anymatch>micromatch>extglob>define-property": { "packages": { "gulp>gulp-cli>matchdep>micromatch>define-property>is-descriptor": true } }, - "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets": { + "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets": { "globals": { "__filename": true }, "packages": { + "gulp-watch>chokidar>braces>extend-shallow": true, "gulp-watch>chokidar>braces>snapdragon": true, "gulp-watch>chokidar>braces>to-regex": true, - "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>debug": true, - "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>define-property": true, - "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>extend-shallow": true, + "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>debug": true, + "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property": true, "gulp>gulp-cli>matchdep>micromatch>extglob>expand-brackets>posix-character-classes": true, "gulp>gulp-cli>matchdep>micromatch>regex-not": true } }, - "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>debug": { + "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>debug": { "builtin": { "fs.SyncWriteStream": true, "net.Socket": true, @@ -5124,908 +5106,151 @@ "process": true }, "packages": { - "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>debug>ms": true + "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>debug>ms": true } }, - "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>define-property": { + "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property": { "packages": { - "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>define-property>is-descriptor": true + "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property>is-descriptor": true } }, - "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>define-property>is-descriptor": { + "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property>is-descriptor": { "packages": { - "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-accessor-descriptor": true, - "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-data-descriptor": true, - "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>define-property>is-descriptor>kind-of": true + "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-accessor-descriptor": true, + "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-data-descriptor": true, + "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property>is-descriptor>kind-of": true } }, - "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-accessor-descriptor": { + "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-accessor-descriptor": { "packages": { - "gulp-watch>anymatch>micromatch>kind-of": true + "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-accessor-descriptor>kind-of": true } }, - "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-data-descriptor": { + "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-accessor-descriptor>kind-of": { "packages": { - "gulp-watch>anymatch>micromatch>kind-of": true + "browserify>insert-module-globals>is-buffer": true } }, - "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>extend-shallow": { + "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-data-descriptor": { "packages": { - "gulp-watch>chokidar>readdirp>micromatch>extglob>expand-brackets>extend-shallow>is-extendable": true + "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-data-descriptor>kind-of": true } }, - "gulp-watch>chokidar>readdirp>micromatch>extglob>extend-shallow": { + "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-data-descriptor>kind-of": { "packages": { - "gulp-watch>chokidar>readdirp>micromatch>extglob>extend-shallow>is-extendable": true + "browserify>insert-module-globals>is-buffer": true } }, - "gulp-watch>chokidar>upath": { - "builtin": { - "path": true + "gulp>glob-watcher>anymatch>normalize-path": { + "packages": { + "vinyl>remove-trailing-separator": true } }, - "gulp-watch>fancy-log": { - "globals": { - "console": true, - "process.argv.indexOf": true, - "process.stderr.write": true, - "process.stdout.write": true - }, - "packages": { - "fancy-log>ansi-gray": true, - "fancy-log>color-support": true, - "fancy-log>time-stamp": true - } - }, - "gulp-watch>glob-parent": { - "builtin": { - "os.platform": true, - "path": true - }, - "packages": { - "gulp-watch>glob-parent>is-glob": true, - "gulp-watch>glob-parent>path-dirname": true - } - }, - "gulp-watch>glob-parent>is-glob": { - "packages": { - "gulp-watch>glob-parent>is-glob>is-extglob": true - } - }, - "gulp-watch>glob-parent>path-dirname": { - "builtin": { - "path": true, - "util.inspect": true - }, - "globals": { - "process.platform": true - } - }, - "gulp-watch>path-is-absolute": { - "globals": { - "process.platform": true - } - }, - "gulp-watch>vinyl-file": { + "gulp>glob-watcher>async-done": { "builtin": { - "path.resolve": true + "domain.create": true }, "globals": { - "process.cwd": true + "process.nextTick": true }, "packages": { - "del>globby>pinkie-promise": true, - "gulp-watch>vinyl-file>pify": true, - "gulp-watch>vinyl-file>strip-bom": true, - "gulp-watch>vinyl-file>strip-bom-stream": true, - "gulp-watch>vinyl-file>vinyl": true, - "webpack>graceful-fs": true + "end-of-stream": true, + "gulp>glob-watcher>async-done>process-nextick-args": true, + "gulp>glob-watcher>async-done>stream-exhaust": true, + "pump>once": true } }, - "gulp-watch>vinyl-file>strip-bom": { + "gulp>glob-watcher>async-done>process-nextick-args": { "globals": { - "Buffer.isBuffer": true - }, - "packages": { - "gulp>vinyl-fs>remove-bom-buffer>is-utf8": true - } - }, - "gulp-watch>vinyl-file>strip-bom-stream": { - "packages": { - "gulp-watch>vinyl-file>strip-bom": true, - "gulp-watch>vinyl-file>strip-bom-stream>first-chunk-stream": true + "process": true } }, - "gulp-watch>vinyl-file>strip-bom-stream>first-chunk-stream": { + "gulp>glob-watcher>async-done>stream-exhaust": { "builtin": { + "stream.Writable": true, "util.inherits": true }, "globals": { - "Buffer.concat": true, "setImmediate": true - }, - "packages": { - "readable-stream": true } }, - "gulp-watch>vinyl-file>vinyl": { + "gulp>glob-watcher>chokidar": { "builtin": { - "buffer.Buffer": true, + "events.EventEmitter": true, + "fs": true, "path.basename": true, "path.dirname": true, "path.extname": true, "path.join": true, "path.relative": true, - "stream.PassThrough": true, - "stream.Stream": true - }, - "globals": { - "process.cwd": true - }, - "packages": { - "gulp-watch>vinyl-file>vinyl>clone": true, - "gulp-watch>vinyl-file>vinyl>clone-stats": true, - "gulp-watch>vinyl-file>vinyl>replace-ext": true - } - }, - "gulp-watch>vinyl-file>vinyl>clone": { - "globals": { - "Buffer": true - } - }, - "gulp-watch>vinyl-file>vinyl>clone-stats": { - "builtin": { - "fs.Stats": true - } - }, - "gulp-watch>vinyl-file>vinyl>replace-ext": { - "builtin": { - "path.basename": true, - "path.dirname": true, - "path.extname": true, - "path.join": true - } - }, - "gulp-zip": { - "builtin": { - "buffer.constants.MAX_LENGTH": true, - "path.join": true - }, - "packages": { - "gulp-zip>get-stream": true, - "gulp-zip>plugin-error": true, - "gulp-zip>through2": true, - "gulp-zip>yazl": true, - "vinyl": true - } - }, - "gulp-zip>get-stream": { - "builtin": { - "buffer.constants.MAX_LENGTH": true, - "stream.PassThrough": true + "path.resolve": true, + "path.sep": true }, "globals": { - "Buffer.concat": true - }, - "packages": { - "pump": true - } - }, - "gulp-zip>plugin-error": { - "builtin": { - "util.inherits": true + "clearTimeout": true, + "console.error": true, + "process.env.CHOKIDAR_INTERVAL": true, + "process.env.CHOKIDAR_PRINT_FSEVENTS_REQUIRE_ERROR": true, + "process.env.CHOKIDAR_USEPOLLING": true, + "process.nextTick": true, + "process.platform": true, + "setTimeout": true }, "packages": { - "gulp-watch>ansi-colors": true, - "gulp-zip>plugin-error>arr-diff": true, - "gulp-zip>plugin-error>arr-union": true, - "gulp-zip>plugin-error>extend-shallow": true - } - }, - "gulp-zip>plugin-error>extend-shallow": { - "packages": { - "gulp-zip>plugin-error>extend-shallow>assign-symbols": true, - "gulp-zip>plugin-error>extend-shallow>is-extendable": true - } - }, - "gulp-zip>plugin-error>extend-shallow>is-extendable": { - "packages": { - "@babel/register>clone-deep>is-plain-object": true + "eslint>is-glob": true, + "gulp-watch>chokidar>async-each": true, + "gulp-watch>glob-parent": true, + "gulp-watch>path-is-absolute": true, + "gulp>glob-watcher>anymatch": true, + "gulp>glob-watcher>chokidar>braces": true, + "gulp>glob-watcher>chokidar>is-binary-path": true, + "gulp>glob-watcher>chokidar>normalize-path": true, + "gulp>glob-watcher>chokidar>readdirp": true, + "gulp>glob-watcher>chokidar>upath": true, + "pumpify>inherits": true } }, - "gulp-zip>through2": { - "builtin": { - "util.inherits": true - }, - "globals": { - "process.nextTick": true - }, + "gulp>glob-watcher>chokidar>braces": { "packages": { - "gulp-zip>through2>readable-stream": true + "gulp-watch>chokidar>braces>extend-shallow": true, + "gulp-watch>chokidar>braces>repeat-element": true, + "gulp-watch>chokidar>braces>snapdragon": true, + "gulp-watch>chokidar>braces>snapdragon-node": true, + "gulp-watch>chokidar>braces>split-string": true, + "gulp-watch>chokidar>braces>to-regex": true, + "gulp>glob-watcher>chokidar>braces>fill-range": true, + "gulp>gulp-cli>isobject": true, + "gulp>gulp-cli>matchdep>micromatch>array-unique": true, + "gulp>undertaker>arr-flatten": true } }, - "gulp-zip>through2>readable-stream": { + "gulp>glob-watcher>chokidar>braces>fill-range": { "builtin": { - "buffer.Buffer": true, - "events.EventEmitter": true, - "stream": true, - "util": true - }, - "globals": { - "process.env.READABLE_STREAM": true, - "process.nextTick": true, - "process.stderr": true, - "process.stdout": true + "util.inspect": true }, "packages": { - "@storybook/api>util-deprecate": true, - "browserify>string_decoder": true, - "pumpify>inherits": true + "gulp-watch>chokidar>braces>extend-shallow": true, + "gulp>glob-watcher>chokidar>braces>fill-range>is-number": true, + "gulp>glob-watcher>chokidar>braces>fill-range>to-regex-range": true, + "stylelint>@stylelint/postcss-markdown>remark>remark-parse>repeat-string": true } }, - "gulp-zip>yazl": { - "builtin": { - "events.EventEmitter": true, - "fs.createReadStream": true, - "fs.stat": true, - "stream.PassThrough": true, - "stream.Transform": true, - "util.inherits": true, - "zlib.DeflateRaw": true, - "zlib.deflateRaw": true - }, - "globals": { - "Buffer": true, - "setImmediate": true, - "utf8FileName.length": true - }, + "gulp>glob-watcher>chokidar>braces>fill-range>is-number": { "packages": { - "gulp-zip>yazl>buffer-crc32": true - } - }, - "gulp-zip>yazl>buffer-crc32": { - "builtin": { - "buffer.Buffer": true + "gulp>glob-watcher>chokidar>braces>fill-range>is-number>kind-of": true } }, - "gulp>glob-watcher": { + "gulp>glob-watcher>chokidar>braces>fill-range>is-number>kind-of": { "packages": { - "gulp>glob-watcher>anymatch": true, - "gulp>glob-watcher>async-done": true, - "gulp>glob-watcher>chokidar": true, - "gulp>glob-watcher>is-negated-glob": true, - "gulp>glob-watcher>just-debounce": true, - "gulp>undertaker>object.defaults": true + "browserify>insert-module-globals>is-buffer": true } }, - "gulp>glob-watcher>anymatch": { - "builtin": { - "path.sep": true - }, - "packages": { - "gulp>glob-watcher>anymatch>micromatch": true, - "gulp>glob-watcher>anymatch>normalize-path": true - } - }, - "gulp>glob-watcher>anymatch>micromatch": { - "builtin": { - "path.basename": true, - "path.sep": true, - "util.inspect": true - }, - "globals": { - "process.platform": true - }, - "packages": { - "@babel/register>clone-deep>kind-of": true, - "gulp-watch>chokidar>braces>snapdragon": true, - "gulp-watch>chokidar>braces>to-regex": true, - "gulp-zip>plugin-error>arr-diff": true, - "gulp>glob-watcher>anymatch>micromatch>define-property": true, - "gulp>glob-watcher>anymatch>micromatch>extend-shallow": true, - "gulp>glob-watcher>anymatch>micromatch>extglob": true, - "gulp>glob-watcher>chokidar>braces": true, - "gulp>gulp-cli>liftoff>fined>object.pick": true, - "gulp>gulp-cli>matchdep>micromatch>array-unique": true, - "gulp>gulp-cli>matchdep>micromatch>fragment-cache": true, - "gulp>gulp-cli>matchdep>micromatch>nanomatch": true, - "gulp>gulp-cli>matchdep>micromatch>regex-not": true - } - }, - "gulp>glob-watcher>anymatch>micromatch>define-property": { - "packages": { - "gulp>gulp-cli>isobject": true, - "gulp>gulp-cli>matchdep>micromatch>define-property>is-descriptor": true - } - }, - "gulp>glob-watcher>anymatch>micromatch>extend-shallow": { - "packages": { - "gulp-zip>plugin-error>extend-shallow>assign-symbols": true, - "gulp>glob-watcher>anymatch>micromatch>extend-shallow>is-extendable": true - } - }, - "gulp>glob-watcher>anymatch>micromatch>extend-shallow>is-extendable": { - "packages": { - "@babel/register>clone-deep>is-plain-object": true - } - }, - "gulp>glob-watcher>anymatch>micromatch>extglob": { - "packages": { - "gulp-watch>chokidar>braces>extend-shallow": true, - "gulp-watch>chokidar>braces>snapdragon": true, - "gulp-watch>chokidar>braces>to-regex": true, - "gulp>glob-watcher>anymatch>micromatch>extglob>define-property": true, - "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets": true, - "gulp>gulp-cli>matchdep>micromatch>array-unique": true, - "gulp>gulp-cli>matchdep>micromatch>fragment-cache": true, - "gulp>gulp-cli>matchdep>micromatch>regex-not": true - } - }, - "gulp>glob-watcher>anymatch>micromatch>extglob>define-property": { - "packages": { - "gulp>gulp-cli>matchdep>micromatch>define-property>is-descriptor": true - } - }, - "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets": { - "globals": { - "__filename": true - }, - "packages": { - "gulp-watch>chokidar>braces>extend-shallow": true, - "gulp-watch>chokidar>braces>snapdragon": true, - "gulp-watch>chokidar>braces>to-regex": true, - "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>debug": true, - "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property": true, - "gulp>gulp-cli>matchdep>micromatch>extglob>expand-brackets>posix-character-classes": true, - "gulp>gulp-cli>matchdep>micromatch>regex-not": true - } - }, - "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>debug": { - "builtin": { - "fs.SyncWriteStream": true, - "net.Socket": true, - "tty.WriteStream": true, - "tty.isatty": true, - "util": true - }, - "globals": { - "chrome": true, - "console": true, - "document": true, - "localStorage": true, - "navigator": true, - "process": true - }, - "packages": { - "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>debug>ms": true - } - }, - "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property": { - "packages": { - "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property>is-descriptor": true - } - }, - "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property>is-descriptor": { - "packages": { - "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-accessor-descriptor": true, - "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-data-descriptor": true, - "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property>is-descriptor>kind-of": true - } - }, - "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-accessor-descriptor": { - "packages": { - "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-accessor-descriptor>kind-of": true - } - }, - "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-accessor-descriptor>kind-of": { - "packages": { - "browserify>insert-module-globals>is-buffer": true - } - }, - "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-data-descriptor": { - "packages": { - "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-data-descriptor>kind-of": true - } - }, - "gulp>glob-watcher>anymatch>micromatch>extglob>expand-brackets>define-property>is-descriptor>is-data-descriptor>kind-of": { - "packages": { - "browserify>insert-module-globals>is-buffer": true - } - }, - "gulp>glob-watcher>anymatch>normalize-path": { - "packages": { - "vinyl>remove-trailing-separator": true - } - }, - "gulp>glob-watcher>async-done": { - "builtin": { - "domain.create": true - }, - "globals": { - "process.nextTick": true - }, - "packages": { - "end-of-stream": true, - "gulp>glob-watcher>async-done>process-nextick-args": true, - "gulp>glob-watcher>async-done>stream-exhaust": true, - "pump>once": true - } - }, - "gulp>glob-watcher>async-done>process-nextick-args": { - "globals": { - "process": true - } - }, - "gulp>glob-watcher>async-done>stream-exhaust": { - "builtin": { - "stream.Writable": true, - "util.inherits": true - }, - "globals": { - "setImmediate": true - } - }, - "gulp>glob-watcher>chokidar": { - "builtin": { - "events.EventEmitter": true, - "fs": true, - "path.basename": true, - "path.dirname": true, - "path.extname": true, - "path.join": true, - "path.relative": true, - "path.resolve": true, - "path.sep": true - }, - "globals": { - "clearTimeout": true, - "console.error": true, - "process.env.CHOKIDAR_INTERVAL": true, - "process.env.CHOKIDAR_PRINT_FSEVENTS_REQUIRE_ERROR": true, - "process.env.CHOKIDAR_USEPOLLING": true, - "process.nextTick": true, - "process.platform": true, - "setTimeout": true - }, - "packages": { - "eslint>is-glob": true, - "gulp-watch>chokidar>async-each": true, - "gulp-watch>glob-parent": true, - "gulp-watch>path-is-absolute": true, - "gulp>glob-watcher>anymatch": true, - "gulp>glob-watcher>chokidar>braces": true, - "gulp>glob-watcher>chokidar>fsevents": true, - "gulp>glob-watcher>chokidar>is-binary-path": true, - "gulp>glob-watcher>chokidar>normalize-path": true, - "gulp>glob-watcher>chokidar>readdirp": true, - "gulp>glob-watcher>chokidar>upath": true, - "pumpify>inherits": true - } - }, - "gulp>glob-watcher>chokidar>braces": { - "packages": { - "gulp-watch>chokidar>braces>extend-shallow": true, - "gulp-watch>chokidar>braces>repeat-element": true, - "gulp-watch>chokidar>braces>snapdragon": true, - "gulp-watch>chokidar>braces>snapdragon-node": true, - "gulp-watch>chokidar>braces>split-string": true, - "gulp-watch>chokidar>braces>to-regex": true, - "gulp>glob-watcher>chokidar>braces>fill-range": true, - "gulp>gulp-cli>isobject": true, - "gulp>gulp-cli>matchdep>micromatch>array-unique": true, - "gulp>undertaker>arr-flatten": true - } - }, - "gulp>glob-watcher>chokidar>braces>fill-range": { - "builtin": { - "util.inspect": true - }, - "packages": { - "gulp-watch>chokidar>braces>extend-shallow": true, - "gulp>glob-watcher>chokidar>braces>fill-range>is-number": true, - "gulp>glob-watcher>chokidar>braces>fill-range>to-regex-range": true, - "stylelint>@stylelint/postcss-markdown>remark>remark-parse>repeat-string": true - } - }, - "gulp>glob-watcher>chokidar>braces>fill-range>is-number": { - "packages": { - "gulp>glob-watcher>chokidar>braces>fill-range>is-number>kind-of": true - } - }, - "gulp>glob-watcher>chokidar>braces>fill-range>is-number>kind-of": { - "packages": { - "browserify>insert-module-globals>is-buffer": true - } - }, - "gulp>glob-watcher>chokidar>braces>fill-range>to-regex-range": { + "gulp>glob-watcher>chokidar>braces>fill-range>to-regex-range": { "packages": { "gulp>glob-watcher>chokidar>braces>fill-range>is-number": true, "stylelint>@stylelint/postcss-markdown>remark>remark-parse>repeat-string": true } }, - "gulp>glob-watcher>chokidar>fsevents": { - "builtin": { - "events.EventEmitter": true, - "fs.stat": true, - "path.join": true, - "util.inherits": true - }, - "globals": { - "__dirname": true, - "process.nextTick": true, - "process.platform": true, - "setImmediate": true - }, - "packages": { - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp": true - } - }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp": { - "builtin": { - "events.EventEmitter": true, - "fs.existsSync": true, - "fs.readFileSync": true, - "fs.renameSync": true, - "path.dirname": true, - "path.existsSync": true, - "path.join": true, - "path.resolve": true, - "url.parse": true, - "url.resolve": true, - "util.inherits": true - }, - "globals": { - "__dirname": true, - "console.log": true, - "process.arch": true, - "process.cwd": true, - "process.env": true, - "process.platform": true, - "process.version.substr": true, - "process.versions": true - }, - "packages": { - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>detect-libc": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>nopt": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>rimraf": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>semver": true - } - }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>detect-libc": { - "builtin": { - "child_process.spawnSync": true, - "fs.readdirSync": true, - "os.platform": true - }, - "globals": { - "process.env": true - } - }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>nopt": { - "builtin": { - "path": true, - "stream.Stream": true, - "url": true - }, - "globals": { - "console": true, - "process.argv": true, - "process.env.DEBUG_NOPT": true, - "process.env.NOPT_DEBUG": true, - "process.platform": true - }, - "packages": { - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>nopt>abbrev": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>nopt>osenv": true - } - }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>nopt>osenv": { - "builtin": { - "child_process.exec": true, - "path": true - }, - "globals": { - "process.env.COMPUTERNAME": true, - "process.env.ComSpec": true, - "process.env.EDITOR": true, - "process.env.HOSTNAME": true, - "process.env.PATH": true, - "process.env.PROMPT": true, - "process.env.PS1": true, - "process.env.Path": true, - "process.env.SHELL": true, - "process.env.USER": true, - "process.env.USERDOMAIN": true, - "process.env.USERNAME": true, - "process.env.VISUAL": true, - "process.env.path": true, - "process.nextTick": true, - "process.platform": true - }, - "packages": { - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>nopt>osenv>os-homedir": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>nopt>osenv>os-tmpdir": true - } - }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>nopt>osenv>os-homedir": { - "builtin": { - "os.homedir": true - }, - "globals": { - "process.env": true, - "process.getuid": true, - "process.platform": true - } - }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>nopt>osenv>os-tmpdir": { - "globals": { - "process.env.SystemRoot": true, - "process.env.TEMP": true, - "process.env.TMP": true, - "process.env.TMPDIR": true, - "process.env.windir": true, - "process.platform": true - } - }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog": { - "builtin": { - "events.EventEmitter": true, - "util": true - }, - "globals": { - "process.nextTick": true, - "process.stderr": true - }, - "packages": { - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>console-control-strings": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>gauge": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>set-blocking": true - } - }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet": { - "builtin": { - "events.EventEmitter": true, - "util.inherits": true - }, - "packages": { - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet>delegates": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet>readable-stream": true - } - }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet>readable-stream": { - "builtin": { - "events.EventEmitter": true, - "stream": true, - "util": true - }, - "globals": { - "process.browser": true, - "process.env.READABLE_STREAM": true, - "process.stderr": true, - "process.stdout": true, - "process.version.slice": true, - "setImmediate": true - }, - "packages": { - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet>readable-stream>core-util-is": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet>readable-stream>isarray": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet>readable-stream>process-nextick-args": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet>readable-stream>string_decoder": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet>readable-stream>util-deprecate": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>rimraf>glob>inherits": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>tar>safe-buffer": true - } - }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet>readable-stream>core-util-is": { - "globals": { - "Buffer.isBuffer": true - } - }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet>readable-stream>process-nextick-args": { - "globals": { - "process": true - } - }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet>readable-stream>string_decoder": { - "packages": { - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>tar>safe-buffer": true - } - }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>are-we-there-yet>readable-stream>util-deprecate": { - "builtin": { - "util.deprecate": true - } - }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>gauge": { - "builtin": { - "util.format": true - }, - "globals": { - "clearInterval": true, - "process": true, - "setImmediate": true, - "setInterval": true - }, - "packages": { - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>console-control-strings": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>gauge>aproba": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>gauge>has-unicode": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>gauge>object-assign": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>gauge>signal-exit": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>gauge>string-width": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>gauge>strip-ansi": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>gauge>wide-align": true - } - }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>gauge>has-unicode": { - "builtin": { - "os.type": true - }, - "globals": { - "process.env.LANG": true, - "process.env.LC_ALL": true, - "process.env.LC_CTYPE": true - } - }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>gauge>signal-exit": { - "builtin": { - "assert.equal": true, - "events": true - }, - "globals": { - "process": true - } - }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>gauge>string-width": { - "packages": { - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>gauge>string-width>code-point-at": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>gauge>string-width>is-fullwidth-code-point": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>gauge>strip-ansi": true - } - }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>gauge>string-width>is-fullwidth-code-point": { - "packages": { - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>gauge>string-width>is-fullwidth-code-point>number-is-nan": true - } - }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>gauge>strip-ansi": { - "packages": { - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>gauge>strip-ansi>ansi-regex": true - } - }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>gauge>wide-align": { - "packages": { - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>gauge>string-width": true - } - }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>npmlog>set-blocking": { - "globals": { - "process.stderr": true, - "process.stdout": true - } - }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>rimraf": { - "builtin": { - "assert": true, - "fs": true, - "path.join": true - }, - "globals": { - "process.platform": true, - "setTimeout": true - }, - "packages": { - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>rimraf>glob": true - } - }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>rimraf>glob": { - "builtin": { - "assert": true, - "events.EventEmitter": true, - "fs.lstat": true, - "fs.lstatSync": true, - "fs.readdir": true, - "fs.readdirSync": true, - "fs.stat": true, - "fs.statSync": true, - "path.join": true, - "path.resolve": true, - "util": true - }, - "globals": { - "console.error": true, - "process.cwd": true, - "process.nextTick": true, - "process.platform": true - }, - "packages": { - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>rimraf>glob>fs.realpath": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>rimraf>glob>inflight": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>rimraf>glob>inherits": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>rimraf>glob>minimatch": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>rimraf>glob>once": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>rimraf>glob>path-is-absolute": true - } - }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>rimraf>glob>fs.realpath": { - "builtin": { - "fs.lstat": true, - "fs.lstatSync": true, - "fs.readlink": true, - "fs.readlinkSync": true, - "fs.realpath": true, - "fs.realpathSync": true, - "fs.stat": true, - "fs.statSync": true, - "path.normalize": true, - "path.resolve": true - }, - "globals": { - "console.error": true, - "console.trace": true, - "process.env.NODE_DEBUG": true, - "process.nextTick": true, - "process.noDeprecation": true, - "process.platform": true, - "process.throwDeprecation": true, - "process.traceDeprecation": true, - "process.version": true - } - }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>rimraf>glob>inflight": { - "globals": { - "process.nextTick": true - }, - "packages": { - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>rimraf>glob>once": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>rimraf>glob>once>wrappy": true - } - }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>rimraf>glob>inherits": { - "builtin": { - "util.inherits": true - } - }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>rimraf>glob>minimatch": { - "builtin": { - "path": true - }, - "globals": { - "console.error": true - }, - "packages": { - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>rimraf>glob>minimatch>brace-expansion": true - } - }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>rimraf>glob>minimatch>brace-expansion": { - "packages": { - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>rimraf>glob>minimatch>brace-expansion>balanced-match": true, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>rimraf>glob>minimatch>brace-expansion>concat-map": true - } - }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>rimraf>glob>once": { - "packages": { - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>rimraf>glob>once>wrappy": true - } - }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>rimraf>glob>path-is-absolute": { - "globals": { - "process.platform": true - } - }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>semver": { - "globals": { - "console": true, - "process": true - } - }, - "gulp>glob-watcher>chokidar>fsevents>node-pre-gyp>tar>safe-buffer": { - "builtin": { - "buffer": true - } - }, "gulp>glob-watcher>chokidar>is-binary-path": { "builtin": { "path.extname": true From 39f9b1e95340df4729dbcd5ee3bdd1805fe626e1 Mon Sep 17 00:00:00 2001 From: PeterYinusa Date: Mon, 9 Jan 2023 19:26:21 +0000 Subject: [PATCH 38/78] fix audit failure for luxon by upgrading (#17106) --- package.json | 2 +- patches/luxon+3.1.0.patch | 22 --------------------- patches/luxon+3.2.1.patch | 40 +++++++++++++++++++++++++++++++++++++++ yarn.lock | 8 ++++---- 4 files changed, 45 insertions(+), 27 deletions(-) delete mode 100644 patches/luxon+3.1.0.patch create mode 100644 patches/luxon+3.2.1.patch diff --git a/package.json b/package.json index 3ed1d685cdef..c31650b4b1c2 100644 --- a/package.json +++ b/package.json @@ -196,7 +196,7 @@ "localforage": "^1.9.0", "lodash": "^4.17.21", "loglevel": "^1.4.1", - "luxon": "^3.1.0", + "luxon": "^3.2.1", "nanoid": "^2.1.6", "nonce-tracker": "^1.0.0", "obj-multiplex": "^1.0.0", diff --git a/patches/luxon+3.1.0.patch b/patches/luxon+3.1.0.patch deleted file mode 100644 index 0cb7a6e659c5..000000000000 --- a/patches/luxon+3.1.0.patch +++ /dev/null @@ -1,22 +0,0 @@ -diff --git a/node_modules/luxon/build/cjs-browser/luxon.js b/node_modules/luxon/build/cjs-browser/luxon.js -index 9ab2b9f..14c2891 100644 ---- a/node_modules/luxon/build/cjs-browser/luxon.js -+++ b/node_modules/luxon/build/cjs-browser/luxon.js -@@ -7373,7 +7373,7 @@ var DateTime = /*#__PURE__*/function () { - */ - ; - -- _proto.toLocaleString = function toLocaleString(formatOpts, opts) { -+ Reflect.defineProperty(_proto, 'toLocaleString', { value: function toLocaleString(formatOpts, opts) { - if (formatOpts === void 0) { - formatOpts = DATE_SHORT; - } -@@ -7383,7 +7383,7 @@ var DateTime = /*#__PURE__*/function () { - } - - return this.isValid ? Formatter.create(this.loc.clone(opts), formatOpts).formatDateTime(this) : INVALID; -- } -+ }}) - /** - * Returns an array of format "parts", meaning individual tokens along with metadata. This is allows callers to post-process individual sections of the formatted output. - * Defaults to the system's locale if no locale has been specified diff --git a/patches/luxon+3.2.1.patch b/patches/luxon+3.2.1.patch new file mode 100644 index 000000000000..c3b672663dd3 --- /dev/null +++ b/patches/luxon+3.2.1.patch @@ -0,0 +1,40 @@ +diff --git a/node_modules/luxon/build/cjs-browser/luxon.js b/node_modules/luxon/build/cjs-browser/luxon.js +index 776c38a..c0f0c21 100644 +--- a/node_modules/luxon/build/cjs-browser/luxon.js ++++ b/node_modules/luxon/build/cjs-browser/luxon.js +@@ -4226,7 +4226,7 @@ var Interval = /*#__PURE__*/function () { + * @example Interval.fromISO('2022-11-07T17:00Z/2022-11-07T19:00Z').toLocaleString({ weekday: 'short', month: 'short', day: '2-digit', hour: '2-digit', minute: '2-digit' }); //=> Mon, Nov 07, 6:00 – 8:00 p + * @return {string} + */; +- _proto.toLocaleString = function toLocaleString(formatOpts, opts) { ++ Reflect.defineProperty(_proto, 'toLocaleString', { value: function toLocaleString(formatOpts, opts) { + if (formatOpts === void 0) { + formatOpts = DATE_SHORT; + } +@@ -4234,7 +4234,7 @@ var Interval = /*#__PURE__*/function () { + opts = {}; + } + return this.isValid ? Formatter.create(this.s.loc.clone(opts), formatOpts).formatInterval(this) : INVALID$1; +- } ++ }}) + + /** + * Returns an ISO 8601-compliant string representation of this Interval. +@@ -6598,7 +6598,7 @@ var DateTime = /*#__PURE__*/function () { + * @example DateTime.now().toLocaleString({ hour: '2-digit', minute: '2-digit', hourCycle: 'h23' }); //=> '11:32' + * @return {string} + */; +- _proto.toLocaleString = function toLocaleString(formatOpts, opts) { ++ Reflect.defineProperty(_proto, 'toLocaleString', { value: function toLocaleString(formatOpts, opts) { + if (formatOpts === void 0) { + formatOpts = DATE_SHORT; + } +@@ -6606,7 +6606,7 @@ var DateTime = /*#__PURE__*/function () { + opts = {}; + } + return this.isValid ? Formatter.create(this.loc.clone(opts), formatOpts).formatDateTime(this) : INVALID; +- } ++ }}) + + /** + * Returns an array of format "parts", meaning individual tokens along with metadata. This is allows callers to post-process individual sections of the formatted output. diff --git a/yarn.lock b/yarn.lock index f10179de912e..a8c3a10bdfcb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17186,10 +17186,10 @@ ltgt@~2.2.0: resolved "https://registry.yarnpkg.com/ltgt/-/ltgt-2.2.1.tgz#f35ca91c493f7b73da0e07495304f17b31f87ee5" integrity sha1-81ypHEk/e3PaDgdJUwTxezH4fuU= -luxon@^3.0.1, luxon@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/luxon/-/luxon-3.1.0.tgz#9ac33d7142b7ea18d4ec8583cdeb0b079abef60d" - integrity sha512-7w6hmKC0/aoWnEsmPCu5Br54BmbmUp5GfcqBxQngRcXJ+q5fdfjEzn7dxmJh2YdDhgW8PccYtlWKSv4tQkrTQg== +luxon@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/luxon/-/luxon-3.2.1.tgz#14f1af209188ad61212578ea7e3d518d18cee45f" + integrity sha512-QrwPArQCNLAKGO/C+ZIilgIuDnEnKx5QYODdDtbFaxzsbZcc/a7WFq7MhsVYgRlwawLtvOUESTlfJ+hc/USqPg== madge@^5.0.1: version "5.0.1" From 925c835a8927f609fd7fd4463f743e319bae3213 Mon Sep 17 00:00:00 2001 From: ryanml Date: Thu, 5 Jan 2023 23:14:32 -0700 Subject: [PATCH 39/78] Onboarding V2: Fix 'Securing my Wallet' when coming from backup reminder after account recovery (#17088) --- .../recovery-phrase/review-recovery-phrase.js | 11 +++++++++-- .../secure-your-wallet/secure-your-wallet.js | 9 +++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/ui/pages/onboarding-flow/recovery-phrase/review-recovery-phrase.js b/ui/pages/onboarding-flow/recovery-phrase/review-recovery-phrase.js index 74673e083c6e..2062fef24281 100644 --- a/ui/pages/onboarding-flow/recovery-phrase/review-recovery-phrase.js +++ b/ui/pages/onboarding-flow/recovery-phrase/review-recovery-phrase.js @@ -1,5 +1,5 @@ import React, { useState } from 'react'; -import { useHistory } from 'react-router-dom'; +import { useHistory, useLocation } from 'react-router-dom'; import PropTypes from 'prop-types'; import Box from '../../../components/ui/box'; import Button from '../../../components/ui/button'; @@ -23,9 +23,14 @@ import RecoveryPhraseChips from './recovery-phrase-chips'; export default function RecoveryPhrase({ secretRecoveryPhrase }) { const history = useHistory(); const t = useI18nContext(); + const { search } = useLocation(); const [copied, handleCopy] = useCopyToClipboard(); const [phraseRevealed, setPhraseRevealed] = useState(false); const [hiddenPhrase, setHiddenPhrase] = useState(false); + const searchParams = new URLSearchParams(search); + const isFromReminderParam = searchParams.get('isFromReminder') + ? '/?isFromReminder=true' + : ''; return (
@@ -122,7 +127,9 @@ export default function RecoveryPhrase({ secretRecoveryPhrase }) { type="primary" className="recovery-phrase__footer--button" onClick={() => { - history.push(ONBOARDING_CONFIRM_SRP_ROUTE); + history.push( + `${ONBOARDING_CONFIRM_SRP_ROUTE}${isFromReminderParam}`, + ); }} > {t('next')} diff --git a/ui/pages/onboarding-flow/secure-your-wallet/secure-your-wallet.js b/ui/pages/onboarding-flow/secure-your-wallet/secure-your-wallet.js index 49fcd83bbd6b..4ae4f049bce8 100644 --- a/ui/pages/onboarding-flow/secure-your-wallet/secure-your-wallet.js +++ b/ui/pages/onboarding-flow/secure-your-wallet/secure-your-wallet.js @@ -1,5 +1,5 @@ import React, { useState } from 'react'; -import { useHistory } from 'react-router-dom'; +import { useHistory, useLocation } from 'react-router-dom'; import { useSelector } from 'react-redux'; import Box from '../../../components/ui/box'; import Button from '../../../components/ui/button'; @@ -23,12 +23,17 @@ import SkipSRPBackup from './skip-srp-backup-popover'; export default function SecureYourWallet() { const history = useHistory(); const t = useI18nContext(); + const { search } = useLocation(); const currentLocale = useSelector(getCurrentLocale); const [showSkipSRPBackupPopover, setShowSkipSRPBackupPopover] = useState(false); + const searchParams = new URLSearchParams(search); + const isFromReminderParam = searchParams.get('isFromReminder') + ? '/?isFromReminder=true' + : ''; const handleClickRecommended = () => { - history.push(ONBOARDING_REVIEW_SRP_ROUTE); + history.push(`${ONBOARDING_REVIEW_SRP_ROUTE}${isFromReminderParam}`); }; const handleClickNotRecommended = () => { From 470bfea08d469835a677b7842f0824b82f1d2faf Mon Sep 17 00:00:00 2001 From: ryanml Date: Mon, 9 Jan 2023 04:19:53 -0700 Subject: [PATCH 40/78] Fix 'Back' navigation from Restore Vault page when accessed from popup window (#17095) --- ui/pages/keychains/restore-vault.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/pages/keychains/restore-vault.js b/ui/pages/keychains/restore-vault.js index 78be005dcffe..cadc70d66f1a 100644 --- a/ui/pages/keychains/restore-vault.js +++ b/ui/pages/keychains/restore-vault.js @@ -61,7 +61,7 @@ class RestoreVaultPage extends Component { onClick={(e) => { e.preventDefault(); this.props.leaveImportSeedScreenState(); - this.props.history.goBack(); + this.props.history.push(DEFAULT_ROUTE); }} href="#" > From ea977111430a67200612500dc8061e9ca461b907 Mon Sep 17 00:00:00 2001 From: Alaa Hadad Date: Mon, 9 Jan 2023 21:14:13 +0400 Subject: [PATCH 41/78] soft disable onramp provider wyre (#17102) --- ui/components/app/deposit-popover/deposit-popover.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ui/components/app/deposit-popover/deposit-popover.js b/ui/components/app/deposit-popover/deposit-popover.js index 81f1715dcfe7..b0128a5f179e 100644 --- a/ui/components/app/deposit-popover/deposit-popover.js +++ b/ui/components/app/deposit-popover/deposit-popover.js @@ -24,7 +24,6 @@ import { getSelectedAddress, getIsBuyableTransakChain, getIsBuyableMoonPayChain, - getIsBuyableWyreChain, getIsBuyableCoinbasePayChain, getIsBuyableCoinbasePayToken, getIsBuyableTransakToken, @@ -46,7 +45,7 @@ const DepositPopover = ({ onClose, token }) => { const address = useSelector(getSelectedAddress); const isBuyableTransakChain = useSelector(getIsBuyableTransakChain); const isBuyableMoonPayChain = useSelector(getIsBuyableMoonPayChain); - const isBuyableWyreChain = useSelector(getIsBuyableWyreChain); + const isBuyableWyreChain = false; const isBuyableCoinbasePayChain = useSelector(getIsBuyableCoinbasePayChain); const isTokenBuyableCoinbasePay = useSelector((state) => From c2ffac6e31f42c6936d1475db81f8cc2c053e460 Mon Sep 17 00:00:00 2001 From: David Walsh Date: Mon, 9 Jan 2023 14:55:48 -0600 Subject: [PATCH 42/78] Fix #16959 - Don't allow user to see welcome or password creation screen after a keyring has been created (#17024) --- .../create-password/create-password.js | 15 +++++++++-- .../onboarding-flow/import-srp/import-srp.js | 11 +++++++- .../onboarding-flow/onboarding-flow.test.js | 4 ++- ui/pages/onboarding-flow/welcome/welcome.js | 26 ++++++++++++++++--- 4 files changed, 49 insertions(+), 7 deletions(-) diff --git a/ui/pages/onboarding-flow/create-password/create-password.js b/ui/pages/onboarding-flow/create-password/create-password.js index 369d45ead4f4..07905d8ec738 100644 --- a/ui/pages/onboarding-flow/create-password/create-password.js +++ b/ui/pages/onboarding-flow/create-password/create-password.js @@ -1,4 +1,4 @@ -import React, { useState, useMemo, useContext } from 'react'; +import React, { useState, useMemo, useContext, useEffect } from 'react'; import PropTypes from 'prop-types'; import { useHistory } from 'react-router-dom'; import zxcvbn from 'zxcvbn'; @@ -27,7 +27,7 @@ import { twoStepStages, } from '../../../components/app/step-progress-bar'; import ZENDESK_URLS from '../../../helpers/constants/zendesk-url'; -import { getFirstTimeFlowType } from '../../../selectors'; +import { getFirstTimeFlowType, getCurrentKeyring } from '../../../selectors'; import { FIRST_TIME_FLOW_TYPES } from '../../../helpers/constants/onboarding'; import { MetaMetricsContext } from '../../../contexts/metametrics'; import { EVENT, EVENT_NAMES } from '../../../../shared/constants/metametrics'; @@ -49,6 +49,17 @@ export default function CreatePassword({ const history = useHistory(); const firstTimeFlowType = useSelector(getFirstTimeFlowType); const trackEvent = useContext(MetaMetricsContext); + const currentKeyring = useSelector(getCurrentKeyring); + + useEffect(() => { + if (currentKeyring) { + if (firstTimeFlowType === FIRST_TIME_FLOW_TYPES.IMPORT) { + history.replace(ONBOARDING_COMPLETION_ROUTE); + } else { + history.replace(ONBOARDING_SECURE_YOUR_WALLET_ROUTE); + } + } + }, [currentKeyring, history, firstTimeFlowType]); const isValid = useMemo(() => { if (!password || !confirmPassword || password !== confirmPassword) { diff --git a/ui/pages/onboarding-flow/import-srp/import-srp.js b/ui/pages/onboarding-flow/import-srp/import-srp.js index 0c2563729587..c7738adb08d2 100644 --- a/ui/pages/onboarding-flow/import-srp/import-srp.js +++ b/ui/pages/onboarding-flow/import-srp/import-srp.js @@ -1,5 +1,6 @@ -import React, { useState } from 'react'; +import React, { useState, useEffect } from 'react'; import { useHistory } from 'react-router-dom'; +import { useSelector } from 'react-redux'; import PropTypes from 'prop-types'; import { TwoStepProgressBar, @@ -17,11 +18,19 @@ import { ONBOARDING_CREATE_PASSWORD_ROUTE } from '../../../helpers/constants/rou import { useI18nContext } from '../../../hooks/useI18nContext'; import ZENDESK_URLS from '../../../helpers/constants/zendesk-url'; import SrpInput from '../../../components/app/srp-input'; +import { getCurrentKeyring } from '../../../selectors'; export default function ImportSRP({ submitSecretRecoveryPhrase }) { const [secretRecoveryPhrase, setSecretRecoveryPhrase] = useState(''); const history = useHistory(); const t = useI18nContext(); + const currentKeyring = useSelector(getCurrentKeyring); + + useEffect(() => { + if (currentKeyring) { + history.replace(ONBOARDING_CREATE_PASSWORD_ROUTE); + } + }, [currentKeyring, history]); return (
diff --git a/ui/pages/onboarding-flow/onboarding-flow.test.js b/ui/pages/onboarding-flow/onboarding-flow.test.js index 9d407e340fcf..1ff71f1c667d 100644 --- a/ui/pages/onboarding-flow/onboarding-flow.test.js +++ b/ui/pages/onboarding-flow/onboarding-flow.test.js @@ -34,7 +34,9 @@ jest.mock('../../store/actions', () => ({ describe('Onboarding Flow', () => { const mockState = { - metamask: {}, + metamask: { + identities: {}, + }, }; const store = configureMockStore()(mockState); diff --git a/ui/pages/onboarding-flow/welcome/welcome.js b/ui/pages/onboarding-flow/welcome/welcome.js index 1ee113dcb3b7..a8a974748615 100644 --- a/ui/pages/onboarding-flow/welcome/welcome.js +++ b/ui/pages/onboarding-flow/welcome/welcome.js @@ -1,6 +1,6 @@ import EventEmitter from 'events'; -import React, { useState } from 'react'; -import { useDispatch } from 'react-redux'; +import React, { useState, useEffect } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; import { useHistory } from 'react-router-dom'; import { Carousel } from 'react-responsive-carousel'; import Mascot from '../../../components/ui/mascot'; @@ -13,13 +13,33 @@ import { } from '../../../helpers/constants/design-system'; import { useI18nContext } from '../../../hooks/useI18nContext'; import { setFirstTimeFlowType } from '../../../store/actions'; -import { ONBOARDING_METAMETRICS } from '../../../helpers/constants/routes'; +import { + ONBOARDING_METAMETRICS, + ONBOARDING_SECURE_YOUR_WALLET_ROUTE, + ONBOARDING_COMPLETION_ROUTE, +} from '../../../helpers/constants/routes'; +import { FIRST_TIME_FLOW_TYPES } from '../../../helpers/constants/onboarding'; +import { getFirstTimeFlowType, getCurrentKeyring } from '../../../selectors'; export default function OnboardingWelcome() { const t = useI18nContext(); const dispatch = useDispatch(); const history = useHistory(); const [eventEmitter] = useState(new EventEmitter()); + const currentKeyring = useSelector(getCurrentKeyring); + const firstTimeFlowType = useSelector(getFirstTimeFlowType); + + // Don't allow users to come back to this screen after they + // have already imported or created a wallet + useEffect(() => { + if (currentKeyring) { + if (firstTimeFlowType === FIRST_TIME_FLOW_TYPES.IMPORT) { + history.replace(ONBOARDING_COMPLETION_ROUTE); + } else { + history.replace(ONBOARDING_SECURE_YOUR_WALLET_ROUTE); + } + } + }, [currentKeyring, history, firstTimeFlowType]); const onCreateClick = () => { dispatch(setFirstTimeFlowType('create')); From f5c95860f7f75b22f999a28a1db3e3af957af103 Mon Sep 17 00:00:00 2001 From: Adnan Sahovic <63151811+adnansahovic@users.noreply.github.com> Date: Thu, 5 Jan 2023 15:58:16 +0100 Subject: [PATCH 43/78] Display large and small numbers as decimals instead of scientific notation on token allowance confirmation screens (#16676) Co-authored-by: VSaric Co-authored-by: Vladimir Saric <92527393+VSaric@users.noreply.github.com> --- shared/constants/tokens.js | 6 + .../custom-spending-cap.js | 107 +++++++++++++----- .../custom-spending-cap.stories.js | 8 +- .../app/custom-spending-cap/index.scss | 8 ++ .../ui/review-spending-cap/index.scss | 4 + .../review-spending-cap.js | 22 ++-- .../review-spending-cap.stories.js | 4 +- ui/pages/token-allowance/token-allowance.js | 30 +++-- 8 files changed, 144 insertions(+), 45 deletions(-) diff --git a/shared/constants/tokens.js b/shared/constants/tokens.js index ef9e7f76aac5..658b19417543 100644 --- a/shared/constants/tokens.js +++ b/shared/constants/tokens.js @@ -1,4 +1,5 @@ import contractMap from '@metamask/contract-metadata'; +import BigNumber from 'bignumber.js'; /** * A normalized list of addresses exported as part of the contractMap in @@ -39,3 +40,8 @@ export const STATIC_MAINNET_TOKEN_LIST = Object.keys(contractMap).reduce( export const TOKEN_API_METASWAP_CODEFI_URL = 'https://token-api.metaswap.codefi.network/tokens/'; +export const MAX_TOKEN_ALLOWANCE_AMOUNT = new BigNumber(2) + .pow(256) + .minus(1) + .toString(10); +export const TOKEN_ALLOWANCE_VALUE_REGEX = /^[0-9]{1,}([,.][0-9]{1,})?$/u; diff --git a/ui/components/app/custom-spending-cap/custom-spending-cap.js b/ui/components/app/custom-spending-cap/custom-spending-cap.js index ef2d13ae3d61..8e976482c92a 100644 --- a/ui/components/app/custom-spending-cap/custom-spending-cap.js +++ b/ui/components/app/custom-spending-cap/custom-spending-cap.js @@ -1,6 +1,7 @@ import React, { useState, useContext, useEffect } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import PropTypes from 'prop-types'; +import BigNumber from 'bignumber.js'; import { I18nContext } from '../../../contexts/i18n'; import Box from '../../ui/box'; import FormField from '../../ui/form-field'; @@ -20,6 +21,15 @@ import { } from '../../../helpers/constants/design-system'; import { getCustomTokenAmount } from '../../../selectors'; import { setCustomTokenAmount } from '../../../ducks/app/app'; +import { calcTokenAmount } from '../../../../shared/lib/transactions-controller-utils'; +import { + conversionGreaterThan, + conversionLTE, +} from '../../../../shared/modules/conversion.utils'; +import { + MAX_TOKEN_ALLOWANCE_AMOUNT, + TOKEN_ALLOWANCE_VALUE_REGEX, +} from '../../../../shared/constants/tokens'; import { CustomSpendingCapTooltip } from './custom-spending-cap-tooltip'; export default function CustomSpendingCap({ @@ -28,6 +38,7 @@ export default function CustomSpendingCap({ dappProposedValue, siteOrigin, passTheErrorText, + decimals, }) { const t = useContext(I18nContext); const dispatch = useDispatch(); @@ -40,8 +51,27 @@ export default function CustomSpendingCap({ ); const inputLogicEmptyStateText = t('inputLogicEmptyState'); + const replaceCommaToDot = (inputValue) => { + return inputValue.replace(/,/gu, '.'); + }; + + const decConversionGreaterThan = (tokenValue, tokenBalance) => { + return conversionGreaterThan( + { value: Number(replaceCommaToDot(tokenValue)), fromNumericBase: 'dec' }, + { value: Number(tokenBalance), fromNumericBase: 'dec' }, + ); + }; + const getInputTextLogic = (inputNumber) => { - if (inputNumber <= currentTokenBalance) { + if ( + conversionLTE( + { + value: Number(replaceCommaToDot(inputNumber)), + fromNumericBase: 'dec', + }, + { value: Number(currentTokenBalance), fromNumericBase: 'dec' }, + ) + ) { return { className: 'custom-spending-cap__lowerValue', description: t('inputLogicEqualOrSmallerNumber', [ @@ -51,11 +81,11 @@ export default function CustomSpendingCap({ fontWeight={FONT_WEIGHT.BOLD} className="custom-spending-cap__input-value-and-token-name" > - {inputNumber} {tokenName} + {replaceCommaToDot(inputNumber)} {tokenName} , ]), }; - } else if (inputNumber > currentTokenBalance) { + } else if (decConversionGreaterThan(inputNumber, currentTokenBalance)) { return { className: 'custom-spending-cap__higherValue', description: t('inputLogicHigherNumber'), @@ -76,7 +106,7 @@ export default function CustomSpendingCap({ const inputTextLogic = getInputTextLogic(valueInput); const inputTextLogicDescription = inputTextLogic.description; - if (valueInput < 0 || isNaN(valueInput)) { + if (valueInput && !TOKEN_ALLOWANCE_VALUE_REGEX.test(valueInput)) { spendingCapError = t('spendingCapError'); setCustomSpendingCapText(t('spendingCapErrorDescription', [siteOrigin])); setError(spendingCapError); @@ -85,6 +115,18 @@ export default function CustomSpendingCap({ setError(''); } + const maxTokenAmount = calcTokenAmount( + MAX_TOKEN_ALLOWANCE_AMOUNT, + decimals, + ); + if (Number(valueInput.length) > 1 && Number(valueInput)) { + const customSpendLimitNumber = new BigNumber(valueInput); + if (customSpendLimitNumber.greaterThan(maxTokenAmount)) { + spendingCapError = t('spendLimitTooLarge'); + setError(spendingCapError); + } + } + dispatch(setCustomTokenAmount(String(valueInput))); }; @@ -98,19 +140,21 @@ export default function CustomSpendingCap({ passTheErrorText(error); }, [error, passTheErrorText]); - const chooseTooltipContentText = - value > currentTokenBalance - ? t('warningTooltipText', [ - - {t('beCareful')} - , - ]) - : t('inputLogicEmptyState'); + const chooseTooltipContentText = decConversionGreaterThan( + value, + currentTokenBalance, + ) + ? t('warningTooltipText', [ + + {t('beCareful')} + , + ]) + : t('inputLogicEmptyState'); return ( <> @@ -133,25 +177,30 @@ export default function CustomSpendingCap({ > @@ -216,11 +267,11 @@ CustomSpendingCap.propTypes = { /** * The current token balance of the token */ - currentTokenBalance: PropTypes.number, + currentTokenBalance: PropTypes.string, /** * The dapp suggested amount */ - dappProposedValue: PropTypes.number, + dappProposedValue: PropTypes.string, /** * The origin of the site generally the URL */ @@ -229,4 +280,8 @@ CustomSpendingCap.propTypes = { * Parent component's callback function passed in order to get the error text */ passTheErrorText: PropTypes.func, + /** + * Number of decimals + */ + decimals: PropTypes.string, }; diff --git a/ui/components/app/custom-spending-cap/custom-spending-cap.stories.js b/ui/components/app/custom-spending-cap/custom-spending-cap.stories.js index 5c30a32e75cd..ba37c62749b7 100644 --- a/ui/components/app/custom-spending-cap/custom-spending-cap.stories.js +++ b/ui/components/app/custom-spending-cap/custom-spending-cap.stories.js @@ -12,7 +12,7 @@ export default { control: { type: 'number' }, }, dappProposedValue: { - control: { type: 'number' }, + control: { type: 'text' }, }, siteOrigin: { control: { type: 'text' }, @@ -20,12 +20,16 @@ export default { passTheErrorText: { action: 'passTheErrorText', }, + decimals: { + control: 'text', + }, }, args: { tokenName: 'DAI', currentTokenBalance: 200.12, - dappProposedValue: 7, + dappProposedValue: '7', siteOrigin: 'Uniswap.org', + decimals: '4', }, }; diff --git a/ui/components/app/custom-spending-cap/index.scss b/ui/components/app/custom-spending-cap/index.scss index 3864e3618f45..2377aec1f656 100644 --- a/ui/components/app/custom-spending-cap/index.scss +++ b/ui/components/app/custom-spending-cap/index.scss @@ -12,11 +12,19 @@ width: 100%; } + &__description { + word-break: break-word; + } + #custom-spending-cap-input-value { color: var(--color-error-default); padding-inline-end: 60px; } + #custom-spending-cap { + padding-inline-end: 60px; + } + input[type='number']::-webkit-inner-spin-button, input[type='number']:hover::-webkit-inner-spin-button { -webkit-appearance: none; diff --git a/ui/components/ui/review-spending-cap/index.scss b/ui/components/ui/review-spending-cap/index.scss index c9000d842f6a..aa84a9f8b9a8 100644 --- a/ui/components/ui/review-spending-cap/index.scss +++ b/ui/components/ui/review-spending-cap/index.scss @@ -25,4 +25,8 @@ i { font-size: $font-size-h7; } + + &__value { + word-break: break-word; + } } diff --git a/ui/components/ui/review-spending-cap/review-spending-cap.js b/ui/components/ui/review-spending-cap/review-spending-cap.js index bce1743455e3..c4948af2eb2c 100644 --- a/ui/components/ui/review-spending-cap/review-spending-cap.js +++ b/ui/components/ui/review-spending-cap/review-spending-cap.js @@ -15,6 +15,7 @@ import { TEXT_ALIGN, SIZES, } from '../../../helpers/constants/design-system'; +import { conversionGreaterThan } from '../../../../shared/modules/conversion.utils'; export default function ReviewSpendingCap({ tokenName, @@ -23,6 +24,10 @@ export default function ReviewSpendingCap({ onEdit, }) { const t = useContext(I18nContext); + const valueIsGreaterThanBalance = conversionGreaterThan( + { value: Number(tokenValue), fromNumericBase: 'dec' }, + { value: Number(currentTokenBalance), fromNumericBase: 'dec' }, + ); return ( - {tokenValue > currentTokenBalance && + {valueIsGreaterThanBalance && t('warningTooltipText', [ , ])} - {tokenValue === 0 && t('revokeSpendingCapTooltipText')} + {Number(tokenValue) === 0 && + t('revokeSpendingCapTooltipText')} } > - {tokenValue > currentTokenBalance && ( + {valueIsGreaterThanBalance && ( )} - {tokenValue === 0 && ( + {Number(tokenValue) === 0 && ( )} @@ -105,11 +111,11 @@ export default function ReviewSpendingCap({ - + currentTokenBalance + valueIsGreaterThanBalance ? COLORS.ERROR_DEFAULT : COLORS.TEXT_DEFAULT } @@ -125,7 +131,7 @@ export default function ReviewSpendingCap({ ReviewSpendingCap.propTypes = { tokenName: PropTypes.string, - currentTokenBalance: PropTypes.number, - tokenValue: PropTypes.number, + currentTokenBalance: PropTypes.string, + tokenValue: PropTypes.string, onEdit: PropTypes.func, }; diff --git a/ui/components/ui/review-spending-cap/review-spending-cap.stories.js b/ui/components/ui/review-spending-cap/review-spending-cap.stories.js index 83832a96690c..15bd1346d255 100644 --- a/ui/components/ui/review-spending-cap/review-spending-cap.stories.js +++ b/ui/components/ui/review-spending-cap/review-spending-cap.stories.js @@ -12,7 +12,7 @@ export default { control: { type: 'number' }, }, tokenValue: { - control: { type: 'number' }, + control: { type: 'text' }, }, onEdit: { action: 'onEdit', @@ -21,7 +21,7 @@ export default { args: { tokenName: 'DAI', currentTokenBalance: 200.12, - tokenValue: 7, + tokenValue: '7', }, }; diff --git a/ui/pages/token-allowance/token-allowance.js b/ui/pages/token-allowance/token-allowance.js index 90103116edba..7c69aabdca92 100644 --- a/ui/pages/token-allowance/token-allowance.js +++ b/ui/pages/token-allowance/token-allowance.js @@ -2,6 +2,7 @@ import React, { useState, useContext } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { useHistory } from 'react-router-dom'; import PropTypes from 'prop-types'; +import BigNumber from 'bignumber.js'; import Box from '../../components/ui/box/box'; import NetworkAccountBalanceHeader from '../../components/app/network-account-balance-header/network-account-balance-header'; import UrlIcon from '../../components/ui/url-icon/url-icon'; @@ -50,6 +51,8 @@ import { useGasFeeContext } from '../../contexts/gasFee'; import { getCustomTxParamsData } from '../confirm-approve/confirm-approve.util'; import { setCustomTokenAmount } from '../../ducks/app/app'; import { valuesFor } from '../../helpers/utils/util'; +import { calcTokenAmount } from '../../../shared/lib/transactions-controller-utils'; +import { MAX_TOKEN_ALLOWANCE_AMOUNT } from '../../../shared/constants/tokens'; export default function TokenAllowance({ origin, @@ -94,9 +97,21 @@ export default function TokenAllowance({ const unapprovedTxCount = useSelector(getUnapprovedTxCount); const unapprovedTxs = useSelector(getUnapprovedTransactions); - const customPermissionAmount = customTokenAmount.toString(); + const replaceCommaToDot = (inputValue) => { + return inputValue.replace(/,/gu, '.'); + }; + + let customPermissionAmount = replaceCommaToDot(customTokenAmount).toString(); + + const maxTokenAmount = calcTokenAmount(MAX_TOKEN_ALLOWANCE_AMOUNT, decimals); + if (customTokenAmount.length > 1 && Number(customTokenAmount)) { + const customSpendLimitNumber = new BigNumber(customTokenAmount); + if (customSpendLimitNumber.greaterThan(maxTokenAmount)) { + customPermissionAmount = 0; + } + } - const customTxParamsData = customTokenAmount + const customTxParamsData = customPermissionAmount ? getCustomTxParamsData(data, { customPermissionAmount, decimals, @@ -339,19 +354,20 @@ export default function TokenAllowance({ {isFirstPage ? ( setErrorText(value)} + decimals={decimals} /> ) : ( handleBackClick()} /> From 3fc1ac873b34afd4e6bcbe5aabfa79203417fa36 Mon Sep 17 00:00:00 2001 From: Brad Decker Date: Thu, 5 Jan 2023 09:49:55 -0500 Subject: [PATCH 44/78] add an extra identifier on anonymized duplicate events (#17080) --- app/scripts/controllers/metametrics.js | 14 +- app/scripts/controllers/metametrics.test.js | 192 ++++++++++++++++++++ 2 files changed, 201 insertions(+), 5 deletions(-) diff --git a/app/scripts/controllers/metametrics.js b/app/scripts/controllers/metametrics.js index a7fb978294e6..3edffbec1b79 100644 --- a/app/scripts/controllers/metametrics.js +++ b/app/scripts/controllers/metametrics.js @@ -35,15 +35,18 @@ const defaultCaptureException = (err) => { // The function is used to build a unique messageId for segment messages // It uses actionId and uniqueIdentifier from event if present const buildUniqueMessageId = (args) => { - let messageId = ''; + const messageIdParts = []; if (args.uniqueIdentifier) { - messageId += `${args.uniqueIdentifier}-`; + messageIdParts.push(args.uniqueIdentifier); } if (args.actionId) { - messageId += args.actionId; + messageIdParts.push(args.actionId); } - if (messageId.length) { - return messageId; + if (messageIdParts.length && args.isDuplicateAnonymizedEvent) { + messageIdParts.push('0x000'); + } + if (messageIdParts.length) { + return messageIdParts.join('-'); } return generateRandomId(); }; @@ -530,6 +533,7 @@ export default class MetaMetricsController { this._buildEventPayload({ ...payload, properties: combinedProperties, + isDuplicateAnonymizedEvent: true, }), { ...options, excludeMetaMetricsId: true }, ), diff --git a/app/scripts/controllers/metametrics.test.js b/app/scripts/controllers/metametrics.test.js index be9aed29d36a..fc5ce0f6dec8 100644 --- a/app/scripts/controllers/metametrics.test.js +++ b/app/scripts/controllers/metametrics.test.js @@ -159,6 +159,7 @@ describe('MetaMetricsController', function () { clock = sinon.useFakeTimers(now.getTime()); sinon.stub(Utils, 'generateRandomId').returns('DUMMY_RANDOM_ID'); }); + describe('constructor', function () { it('should properly initialize', function () { const mock = sinon.mock(segment); @@ -677,6 +678,197 @@ describe('MetaMetricsController', function () { }); }); + describe('deterministic messageId', function () { + it('should use the actionId as messageId when provided', function () { + const metaMetricsController = getMetaMetricsController(); + const spy = sinon.spy(segment, 'track'); + metaMetricsController.submitEvent({ + event: 'Fake Event', + category: 'Unit Test', + properties: { foo: 'bar' }, + actionId: '0x001', + }); + assert.ok(spy.calledOnce); + assert.ok( + spy.calledWith({ + event: 'Fake Event', + userId: TEST_META_METRICS_ID, + context: DEFAULT_TEST_CONTEXT, + properties: { + foo: 'bar', + ...DEFAULT_EVENT_PROPERTIES, + }, + messageId: '0x001', + timestamp: new Date(), + }), + ); + }); + + it('should append 0x000 to the actionId of anonymized event when tracking sensitiveProperties', function () { + const metaMetricsController = getMetaMetricsController(); + const spy = sinon.spy(segment, 'track'); + metaMetricsController.submitEvent({ + event: 'Fake Event', + category: 'Unit Test', + sensitiveProperties: { foo: 'bar' }, + actionId: '0x001', + }); + assert.ok(spy.calledTwice); + + assert.ok( + spy.calledWith({ + event: 'Fake Event', + anonymousId: METAMETRICS_ANONYMOUS_ID, + context: DEFAULT_TEST_CONTEXT, + properties: { + foo: 'bar', + ...DEFAULT_EVENT_PROPERTIES, + }, + messageId: '0x001-0x000', + timestamp: new Date(), + }), + ); + assert.ok( + spy.calledWith({ + event: 'Fake Event', + userId: TEST_META_METRICS_ID, + context: DEFAULT_TEST_CONTEXT, + properties: { + ...DEFAULT_EVENT_PROPERTIES, + }, + messageId: '0x001', + timestamp: new Date(), + }), + ); + }); + + it('should use the uniqueIdentifier as messageId when provided', function () { + const metaMetricsController = getMetaMetricsController(); + const spy = sinon.spy(segment, 'track'); + metaMetricsController.submitEvent({ + event: 'Fake Event', + category: 'Unit Test', + properties: { foo: 'bar' }, + uniqueIdentifier: 'transaction-submitted-0000', + }); + assert.ok(spy.calledOnce); + assert.ok( + spy.calledWith({ + event: 'Fake Event', + userId: TEST_META_METRICS_ID, + context: DEFAULT_TEST_CONTEXT, + properties: { + foo: 'bar', + ...DEFAULT_EVENT_PROPERTIES, + }, + messageId: 'transaction-submitted-0000', + timestamp: new Date(), + }), + ); + }); + + it('should append 0x000 to the uniqueIdentifier of anonymized event when tracking sensitiveProperties', function () { + const metaMetricsController = getMetaMetricsController(); + const spy = sinon.spy(segment, 'track'); + metaMetricsController.submitEvent({ + event: 'Fake Event', + category: 'Unit Test', + sensitiveProperties: { foo: 'bar' }, + uniqueIdentifier: 'transaction-submitted-0000', + }); + assert.ok(spy.calledTwice); + assert.ok( + spy.calledWith({ + event: 'Fake Event', + anonymousId: METAMETRICS_ANONYMOUS_ID, + context: DEFAULT_TEST_CONTEXT, + properties: { + foo: 'bar', + ...DEFAULT_EVENT_PROPERTIES, + }, + messageId: 'transaction-submitted-0000-0x000', + timestamp: new Date(), + }), + ); + assert.ok( + spy.calledWith({ + event: 'Fake Event', + userId: TEST_META_METRICS_ID, + context: DEFAULT_TEST_CONTEXT, + properties: { + ...DEFAULT_EVENT_PROPERTIES, + }, + messageId: 'transaction-submitted-0000', + timestamp: new Date(), + }), + ); + }); + + it('should combine the uniqueIdentifier and actionId as messageId when both provided', function () { + const metaMetricsController = getMetaMetricsController(); + const spy = sinon.spy(segment, 'track'); + metaMetricsController.submitEvent({ + event: 'Fake Event', + category: 'Unit Test', + properties: { foo: 'bar' }, + actionId: '0x001', + uniqueIdentifier: 'transaction-submitted-0000', + }); + assert.ok(spy.calledOnce); + assert.ok( + spy.calledWith({ + event: 'Fake Event', + userId: TEST_META_METRICS_ID, + context: DEFAULT_TEST_CONTEXT, + properties: { + foo: 'bar', + ...DEFAULT_EVENT_PROPERTIES, + }, + messageId: 'transaction-submitted-0000-0x001', + timestamp: new Date(), + }), + ); + }); + + it('should append 0x000 to the combined uniqueIdentifier and actionId of anonymized event when tracking sensitiveProperties', function () { + const metaMetricsController = getMetaMetricsController(); + const spy = sinon.spy(segment, 'track'); + metaMetricsController.submitEvent({ + event: 'Fake Event', + category: 'Unit Test', + sensitiveProperties: { foo: 'bar' }, + actionId: '0x001', + uniqueIdentifier: 'transaction-submitted-0000', + }); + assert.ok(spy.calledTwice); + assert.ok( + spy.calledWith({ + event: 'Fake Event', + anonymousId: METAMETRICS_ANONYMOUS_ID, + context: DEFAULT_TEST_CONTEXT, + properties: { + foo: 'bar', + ...DEFAULT_EVENT_PROPERTIES, + }, + messageId: 'transaction-submitted-0000-0x001-0x000', + timestamp: new Date(), + }), + ); + assert.ok( + spy.calledWith({ + event: 'Fake Event', + userId: TEST_META_METRICS_ID, + context: DEFAULT_TEST_CONTEXT, + properties: { + ...DEFAULT_EVENT_PROPERTIES, + }, + messageId: 'transaction-submitted-0000-0x001', + timestamp: new Date(), + }), + ); + }); + }); + describe('_buildUserTraitsObject', function () { it('should return full user traits object on first call', function () { const MOCK_ALL_TOKENS = { From e027a8b966c05ae5aff973b14c79715d1ad67f86 Mon Sep 17 00:00:00 2001 From: PeterYinusa Date: Wed, 11 Jan 2023 12:12:58 +0000 Subject: [PATCH 45/78] Update CHANGELOG.md --- CHANGELOG.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bbd8241cdd16..deaceee281d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -70,7 +70,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [FLASK] Clear notification state on restore ([#16503](https://github.com/MetaMask/metamask-extension/pull/16503)) - [FLASK] Fix a crash that happens after snap install ([#16526](https://github.com/MetaMask/metamask-extension/pull/16526)) - [FLASK] Fix usage of wrong `ethereum` global for `ethereum` endowment ([#16932](https://github.com/MetaMask/metamask-extension/pull/16932)) + ## [10.23.3] +### Changed +- Remove onramp provider Wyre ([#17102](https://github.com/MetaMask/metamask-extension/pull/17102)) ## [10.23.2] ### Fixed @@ -3411,8 +3414,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added the ability to restore accounts from seed words. [Unreleased]: https://github.com/MetaMask/metamask-extension/compare/v10.24.0...HEAD -[10.24.0]: https://github.com/MetaMask/metamask-extension/compare/v10.23.2...v10.24.0 -[Unreleased]: https://github.com/MetaMask/metamask-extension/compare/v10.23.3...HEAD +[10.24.0]: https://github.com/MetaMask/metamask-extension/compare/v10.23.3...v10.24.0 [10.23.3]: https://github.com/MetaMask/metamask-extension/compare/v10.23.2...v10.23.3 [10.23.2]: https://github.com/MetaMask/metamask-extension/compare/v10.23.1...v10.23.2 [10.23.1]: https://github.com/MetaMask/metamask-extension/compare/v10.23.0...v10.23.1 From effbd7f953352261796f859dededd73aaaeaa703 Mon Sep 17 00:00:00 2001 From: Olusegun Akintayo Date: Mon, 19 Dec 2022 18:46:36 +0100 Subject: [PATCH 46/78] Security and Privacy Settings Re-org (#16756) --- app/_locales/de/messages.json | 9 +- app/_locales/el/messages.json | 9 +- app/_locales/en/messages.json | 58 +- app/_locales/es/messages.json | 9 +- app/_locales/es_419/messages.json | 9 +- app/_locales/fr/messages.json | 9 +- app/_locales/hi/messages.json | 9 +- app/_locales/id/messages.json | 9 +- app/_locales/it/messages.json | 9 +- app/_locales/ja/messages.json | 9 +- app/_locales/ko/messages.json | 9 +- app/_locales/ph/messages.json | 9 +- app/_locales/pt/messages.json | 9 +- app/_locales/pt_BR/messages.json | 9 +- app/_locales/ru/messages.json | 9 +- app/_locales/tl/messages.json | 9 +- app/_locales/tr/messages.json | 9 +- app/_locales/vi/messages.json | 9 +- app/_locales/zh_CN/messages.json | 9 +- app/_locales/zh_TW/messages.json | 6 +- app/scripts/controllers/preferences.js | 3 +- app/scripts/lib/util.js | 7 + shared/constants/metametrics.js | 8 + shared/lib/ui-utils.js | 5 + test/e2e/fixture-builder.js | 2 + test/e2e/restore/MetaMaskUserData.json | 3 +- .../app/whats-new-popup/whats-new-popup.js | 2 +- ui/helpers/constants/settings.js | 53 +- ui/helpers/utils/settings-search.test.js | 4 +- .../import-token/import-token.component.js | 6 +- .../advanced-tab/advanced-tab.component.js | 422 +++++--------- .../advanced-tab.component.test.js | 14 +- .../advanced-tab/advanced-tab.container.js | 12 - .../experimental-tab.component.js | 53 -- ui/pages/settings/index.scss | 28 +- .../__snapshots__/security-tab.test.js.snap | 537 +++++++++++++----- .../security-tab/security-tab.component.js | 334 ++++++++++- .../security-tab/security-tab.container.js | 24 +- .../security-tab/security-tab.test.js | 46 +- ui/store/actions.js | 2 - 40 files changed, 1101 insertions(+), 690 deletions(-) diff --git a/app/_locales/de/messages.json b/app/_locales/de/messages.json index fd97a8740c6e..a62bcad4bf86 100644 --- a/app/_locales/de/messages.json +++ b/app/_locales/de/messages.json @@ -1737,12 +1737,6 @@ "invalidSeedPhraseCaseSensitive": { "message": "Ungültige Eingabe! Die geheime Wiederherstellungsphrase berücksichtigt Groß- und Kleinschreibung." }, - "ipfsGateway": { - "message": "IPFS-Gateway" - }, - "ipfsGatewayDescription": { - "message": "Geben Sie die URL des IPFS CID Gateways ein, das für die Auflösung der ENS Inhalte verwendet werden soll." - }, "jazzAndBlockies": { "message": "Jazzicons und Blockies sind zwei verschiedene Arten von einzigartigen Symbolen, mit denen Sie ein Konto auf einen Blick erkennen können." }, @@ -3085,7 +3079,8 @@ "message": "Eingehende Transaktionen anzeigen" }, "showIncomingTransactionsDescription": { - "message": "Aktivieren Sie dies, um Etherscan zu aktivieren und eingehende Transaktionen in der Transaktionsliste anzuzeigen" + "message": "Aktivieren Sie dies, um Etherscan zu aktivieren und eingehende Transaktionen in der Transaktionsliste anzuzeigen", + "description": "$1 is the link to etherscan url and $2 is the link to the privacy policy of consensys APIs" }, "showPermissions": { "message": "Berechtigungen anzeigen" diff --git a/app/_locales/el/messages.json b/app/_locales/el/messages.json index 1f30b46fb34e..a1fa9e39f78d 100644 --- a/app/_locales/el/messages.json +++ b/app/_locales/el/messages.json @@ -1737,12 +1737,6 @@ "invalidSeedPhraseCaseSensitive": { "message": "Μη έγκυρη εισαγωγή! Η Μυστική σας Φράση Ανάκτησης κάνει διάκριση πεζών-κεφαλαίων." }, - "ipfsGateway": { - "message": "Πύλη IPFS" - }, - "ipfsGatewayDescription": { - "message": "Εισάγετε τη διεύθυνση URL της πύλης IPFS CID που θα χρησιμοποιηθεί για την ανάλυση περιεχομένου ENS." - }, "jazzAndBlockies": { "message": "Τα Jazzicons και τα Blockies είναι δύο διαφορετικά στυλ μοναδικών εικονιδίων που σας βοηθούν να αναγνωρίζετε έναν λογαριασμό με μια ματιά." }, @@ -3085,7 +3079,8 @@ "message": "Εμφάνιση Εισερχομένων Συναλλαγών" }, "showIncomingTransactionsDescription": { - "message": "Επιλέξτε αυτό για να χρησιμοποιήσετε Etherscan για να εμφανίσετε τις εισερχόμενες συναλλαγές στη λίστα συναλλαγών" + "message": "Επιλέξτε αυτό για να χρησιμοποιήσετε Etherscan για να εμφανίσετε τις εισερχόμενες συναλλαγές στη λίστα συναλλαγών", + "description": "$1 is the link to etherscan url and $2 is the link to the privacy policy of consensys APIs" }, "showPermissions": { "message": "Εμφάνιση δικαιωμάτων" diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index e5515c752e91..364a507173a2 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -183,6 +183,15 @@ "addContact": { "message": "Add contact" }, + "addCustomIPFSGateway": { + "message": "Add custom IPFS gateway" + }, + "addCustomIPFSGatewayDescription": { + "message": "The IPFS gateway makes it possible to access and view data hosted by third parties. You can add a custom IPFS gateway or continue using the default." + }, + "addCustomNetwork": { + "message": "Add custom network" + }, "addCustomToken": { "message": "Add custom token" }, @@ -418,6 +427,13 @@ "authorizedPermissions": { "message": "You have authorized the following permissions" }, + "autoDetectTokens": { + "message": "Autodetect tokens" + }, + "autoDetectTokensDescription": { + "message": "We use third-party APIs to detect and display new tokens sent to your wallet. Turn off if you don’t want the app to pull data from those services. $1", + "description": "$1 is a link to a support article" + }, "autoLockTimeLimit": { "message": "Auto-lock timer (minutes)" }, @@ -642,6 +658,13 @@ "message": "The network with chain ID $1 may use a different currency symbol ($2) than the one you have entered. Please verify before continuing.", "description": "$1 is the chain id currently entered in the network form and $2 is the return value of nativeCurrency.symbol from chainlist.network" }, + "chooseYourNetwork": { + "message": "Choose your network" + }, + "chooseYourNetworkDescription": { + "message": "We use Infura as our remote procedure call (RPC) provider to offer the most reliable and private access to Ethereum data we can. You can choose your own RPC, but remember that any RPC will receive your IP address and Ethereum wallet to make transactions. Read our $1 to learn more about how Infura handles data.", + "description": "$1 is a link to the privacy policy" + }, "chromeRequiredForHardwareWallets": { "message": "You need to use MetaMask on Google Chrome in order to connect to your Hardware Wallet." }, @@ -1858,12 +1881,6 @@ "invalidSeedPhraseCaseSensitive": { "message": "Invalid input! Secret Recovery Phrase is case sensitive." }, - "ipfsGateway": { - "message": "IPFS Gateway" - }, - "ipfsGatewayDescription": { - "message": "Enter the URL of the IPFS CID gateway to use for ENS content resolution." - }, "jazzAndBlockies": { "message": "Jazzicons and Blockies are two different styles of unique icons that help you identify an account at a glance." }, @@ -2220,6 +2237,9 @@ "networkNameTestnet": { "message": "Testnet" }, + "networkProvider": { + "message": "Network provider" + }, "networkSettingsChainIdDescription": { "message": "The chain ID is used for signing transactions. It must match the chain ID returned by the network. You can enter a decimal or '0x'-prefixed hexadecimal number, but we will display the number in decimal." }, @@ -2921,6 +2941,9 @@ "priorityFeeProperCase": { "message": "Priority Fee" }, + "privacy": { + "message": "Privacy" + }, "privacyMsg": { "message": "Privacy policy" }, @@ -3187,6 +3210,9 @@ "secureWallet": { "message": "Secure wallet" }, + "security": { + "message": "Security" + }, "securityAndPrivacy": { "message": "Security & privacy" }, @@ -3359,7 +3385,8 @@ "message": "Show incoming transactions" }, "showIncomingTransactionsDescription": { - "message": "Select this to use Etherscan to show incoming transactions in the transactions list" + "message": "This relies on $1 which will have access to your Ethereum address and your IP address. $2", + "description": "$1 is the link to etherscan url and $2 is the link to the privacy policy of consensys APIs" }, "showPermissions": { "message": "Show permissions" @@ -4168,6 +4195,9 @@ "tokenList": { "message": "Token lists:" }, + "tokenNftAutoDetection": { + "message": "Token and NFT autodetection" + }, "tokenScamSecurityRisk": { "message": "token scams and security risks" }, @@ -4295,6 +4325,9 @@ "transactionUpdated": { "message": "Transaction updated at $2." }, + "transactions": { + "message": "Transactions" + }, "transfer": { "message": "Transfer" }, @@ -4410,7 +4443,16 @@ "message": "Autodetect NFTs" }, "useCollectibleDetectionDescription": { - "message": "Displaying NFTs media & data may expose your IP address to centralized servers. Third-party APIs (like OpenSea) are used to detect NFTs in your wallet. This exposes your account address with those services. Leave this disabled if you don’t want the app to pull data from those those services." + "message": "We use third-party APIs to detect NFTs in your wallet, which means your IP address may be exposed to their servers. Leave this feature off if you don't want the app to pull data from those services." + }, + "useCollectibleDetectionDescriptionLine2": { + "message": "Additionally, be aware that:" + }, + "useCollectibleDetectionDescriptionLine3": { + "message": "NFT metadata may contain links to scams or phishing sites." + }, + "useCollectibleDetectionDescriptionLine4": { + "message": "Anyone can airdrop NFTs to your account. This can include offensive content that might be automatically displayed in your wallet." }, "useDefault": { "message": "Use default" diff --git a/app/_locales/es/messages.json b/app/_locales/es/messages.json index 1718e682b588..296b7386429f 100644 --- a/app/_locales/es/messages.json +++ b/app/_locales/es/messages.json @@ -1737,12 +1737,6 @@ "invalidSeedPhraseCaseSensitive": { "message": "¡Entrada inválida! La frase secreta de recuperación distingue entre mayúsculas y minúsculas." }, - "ipfsGateway": { - "message": "Puerta de enlace de IPFS" - }, - "ipfsGatewayDescription": { - "message": "Escriba la dirección URL de la puerta de enlace de IPFS CID para usar la resolución de contenido de ENS." - }, "jazzAndBlockies": { "message": "Jazzicons y Blockies son dos estilos distintos de íconos únicos que pueden ayudarlo a identificar rápidamente una cuenta." }, @@ -3085,7 +3079,8 @@ "message": "Mostrar transacciones entrantes" }, "showIncomingTransactionsDescription": { - "message": "Seleccione esta opción para usar Etherscan para mostrar las transacciones entrantes en la lista de transacciones" + "message": "Seleccione esta opción para usar Etherscan para mostrar las transacciones entrantes en la lista de transacciones", + "description": "$1 is the link to etherscan url and $2 is the link to the privacy policy of consensys APIs" }, "showPermissions": { "message": "Mostrar permisos" diff --git a/app/_locales/es_419/messages.json b/app/_locales/es_419/messages.json index 69fec5dd2b52..217bedc6b4bc 100644 --- a/app/_locales/es_419/messages.json +++ b/app/_locales/es_419/messages.json @@ -1373,12 +1373,6 @@ "invalidSeedPhrase": { "message": "Frase secreta de recuperación no válida" }, - "ipfsGateway": { - "message": "Puerta de enlace de IPFS" - }, - "ipfsGatewayDescription": { - "message": "Escriba la dirección URL de la puerta de enlace de IPFS CID para usar la resolución de contenido de ENS." - }, "jsDeliver": { "message": "jsDeliver" }, @@ -2374,7 +2368,8 @@ "message": "Mostrar transacciones entrantes" }, "showIncomingTransactionsDescription": { - "message": "Seleccione esta opción para usar Etherscan para mostrar las transacciones entrantes en la lista de transacciones" + "message": "Seleccione esta opción para usar Etherscan para mostrar las transacciones entrantes en la lista de transacciones", + "description": "$1 is the link to etherscan url and $2 is the link to the privacy policy of consensys APIs" }, "showPermissions": { "message": "Mostrar permisos" diff --git a/app/_locales/fr/messages.json b/app/_locales/fr/messages.json index b0e325c8d5b0..e68ba408c1dd 100644 --- a/app/_locales/fr/messages.json +++ b/app/_locales/fr/messages.json @@ -1737,12 +1737,6 @@ "invalidSeedPhraseCaseSensitive": { "message": "Entrée invalide ! La phrase secrète de récupération est sensible à la casse." }, - "ipfsGateway": { - "message": "Passerelle IPFS" - }, - "ipfsGatewayDescription": { - "message": "Entrez l’URL de la passerelle CID IPFS à utiliser pour résoudre les contenus ENS." - }, "jazzAndBlockies": { "message": "Les Jazzicons et les Blockies sont deux styles différents d’icônes uniques qui vous aident à identifier un compte en un coup d’œil." }, @@ -3085,7 +3079,8 @@ "message": "Afficher les transactions entrantes" }, "showIncomingTransactionsDescription": { - "message": "Sélectionnez ceci pour utiliser Etherscan afin d’afficher les transactions entrantes dans la liste des transactions" + "message": "Sélectionnez ceci pour utiliser Etherscan afin d’afficher les transactions entrantes dans la liste des transactions", + "description": "$1 is the link to etherscan url and $2 is the link to the privacy policy of consensys APIs" }, "showPermissions": { "message": "Afficher les autorisations" diff --git a/app/_locales/hi/messages.json b/app/_locales/hi/messages.json index 40609d37525f..c705a3216eb3 100644 --- a/app/_locales/hi/messages.json +++ b/app/_locales/hi/messages.json @@ -1737,12 +1737,6 @@ "invalidSeedPhraseCaseSensitive": { "message": "अमान्य निवेश! गुप्त पुनर्प्राप्ति वाक्यांश केस संवेदी है।" }, - "ipfsGateway": { - "message": "IPFS गेटवे" - }, - "ipfsGatewayDescription": { - "message": "ENS सामग्री रिजॉल्यूशन का उपयोग करने के लिए IPFS CID गेटवे का URL दर्ज करें।" - }, "jazzAndBlockies": { "message": "जाज़िकॉन्स और ब्लॉकीज़ विशिष्ट आइकनों की दो अलग-अलग शैलियां हैं जो आपको एक नज़र में किसी अकाउंट की पहचान करने में मदद करती हैं।" }, @@ -3085,7 +3079,8 @@ "message": "आने वाले लेन-देन दिखाएं" }, "showIncomingTransactionsDescription": { - "message": "लेनदेन सूची में आने वाले लेनदेन को दिखाने के लिए Etherscan का उपयोग करने के लिए इसका चयन करें" + "message": "लेनदेन सूची में आने वाले लेनदेन को दिखाने के लिए Etherscan का उपयोग करने के लिए इसका चयन करें", + "description": "$1 is the link to etherscan url and $2 is the link to the privacy policy of consensys APIs" }, "showPermissions": { "message": "अनुमतियां दिखाएं" diff --git a/app/_locales/id/messages.json b/app/_locales/id/messages.json index 6b0bc5b6e952..eaad8d5d8401 100644 --- a/app/_locales/id/messages.json +++ b/app/_locales/id/messages.json @@ -1737,12 +1737,6 @@ "invalidSeedPhraseCaseSensitive": { "message": "Masukan tidak valid! Frasa Pemulihan Rahasia peka terhadap huruf besar/kecil." }, - "ipfsGateway": { - "message": "Gateway IPFS" - }, - "ipfsGatewayDescription": { - "message": "Masukkan URL gateway CID IPFS dan gunakan untuk resolusi konten ENS." - }, "jazzAndBlockies": { "message": "Jazzicons dan Blockies merupakan dua gaya ikon unik yang berbeda untuk membantu Anda mengidentifikasi akun dengan cepat." }, @@ -3085,7 +3079,8 @@ "message": "Tampilkan transaksi masuk" }, "showIncomingTransactionsDescription": { - "message": "Pilih ini untuk menggunakan Etherscan untuk menampilkan transaksi yang masuk di daftar transaksi" + "message": "Pilih ini untuk menggunakan Etherscan untuk menampilkan transaksi yang masuk di daftar transaksi", + "description": "$1 is the link to etherscan url and $2 is the link to the privacy policy of consensys APIs" }, "showPermissions": { "message": "Tampilkan Izin" diff --git a/app/_locales/it/messages.json b/app/_locales/it/messages.json index 4102f1aa97b3..48e5c4c0fab3 100644 --- a/app/_locales/it/messages.json +++ b/app/_locales/it/messages.json @@ -1296,12 +1296,6 @@ "invalidSeedPhrase": { "message": "Frase seed non valida" }, - "ipfsGateway": { - "message": "Portale IPFS" - }, - "ipfsGatewayDescription": { - "message": "Inserisci l'URL del portale IPFS CID da usare per la risoluzione del contenuto ENS." - }, "jsonFile": { "message": "File JSON", "description": "format for importing an account" @@ -1763,7 +1757,8 @@ "message": "Mostra Transazioni in Ingresso" }, "showIncomingTransactionsDescription": { - "message": "Usa Etherscan per visualizzare le transazioni in ingresso nella lista delle transazioni" + "message": "Usa Etherscan per visualizzare le transazioni in ingresso nella lista delle transazioni", + "description": "$1 is the link to etherscan url and $2 is the link to the privacy policy of consensys APIs" }, "showPermissions": { "message": "Mostra permessi" diff --git a/app/_locales/ja/messages.json b/app/_locales/ja/messages.json index ac3b215001f2..4110426c5384 100644 --- a/app/_locales/ja/messages.json +++ b/app/_locales/ja/messages.json @@ -1737,12 +1737,6 @@ "invalidSeedPhraseCaseSensitive": { "message": "入力値が無効です!秘密のリカバリーフレーズは大文字・小文字が区別されます。" }, - "ipfsGateway": { - "message": "IPFSゲートウェイ" - }, - "ipfsGatewayDescription": { - "message": "ENSコンテンツの解決に使用するIPFS CIDゲートウェイのURLを入力します。" - }, "jazzAndBlockies": { "message": "Jazzicon と Blockie は、アカウントを一目で見分けるためのユニークなアイコンであり、2 つの異なるスタイルが特徴です。" }, @@ -3085,7 +3079,8 @@ "message": "受信トランザクションを表示" }, "showIncomingTransactionsDescription": { - "message": "これを選択すると、Etherscanを使用して受信トランザクションがトランザクションリストに表示されます" + "message": "これを選択すると、Etherscanを使用して受信トランザクションがトランザクションリストに表示されます", + "description": "$1 is the link to etherscan url and $2 is the link to the privacy policy of consensys APIs" }, "showPermissions": { "message": "表示許可" diff --git a/app/_locales/ko/messages.json b/app/_locales/ko/messages.json index 42a0759b9a9e..ed68a8d66213 100644 --- a/app/_locales/ko/messages.json +++ b/app/_locales/ko/messages.json @@ -1737,12 +1737,6 @@ "invalidSeedPhraseCaseSensitive": { "message": "입력 오류: 비밀 복구 구문은 대소문자를 구분해야 합니다." }, - "ipfsGateway": { - "message": "IPFS 게이트웨이" - }, - "ipfsGatewayDescription": { - "message": "ENS 콘텐츠 해결에 사용할 IPFS CID 게이트웨이의 URL을 입력하세요." - }, "jazzAndBlockies": { "message": "Jazzicons와 Blockies는 계정을 한눈에 식별할 수 있게 도와주는 두 가지 고유한 아이콘 스타일입니다." }, @@ -3085,7 +3079,8 @@ "message": "수신 거래 표시" }, "showIncomingTransactionsDescription": { - "message": "이 항목을 선택하면 Etherscan을 사용해 거래 목록에 수신 거래를 표시할 수 있습니다." + "message": "이 항목을 선택하면 Etherscan을 사용해 거래 목록에 수신 거래를 표시할 수 있습니다.", + "description": "$1 is the link to etherscan url and $2 is the link to the privacy policy of consensys APIs" }, "showPermissions": { "message": "권한 표시" diff --git a/app/_locales/ph/messages.json b/app/_locales/ph/messages.json index c605c3d5108a..e1c0eb5c3b86 100644 --- a/app/_locales/ph/messages.json +++ b/app/_locales/ph/messages.json @@ -881,12 +881,6 @@ "invalidSeedPhrase": { "message": "Invalid na Secret Recovery Phrase" }, - "ipfsGateway": { - "message": "IPFS Gateway" - }, - "ipfsGatewayDescription": { - "message": "Ilagay ang URL ng IPFS CID gateway para magamit para sa resolusyon ng content ng ENS." - }, "jsonFile": { "message": "JSON File", "description": "format for importing an account" @@ -1538,7 +1532,8 @@ "message": "Ipakita ang Mga Papasok na Transaksyon" }, "showIncomingTransactionsDescription": { - "message": "Piliin ito para gamitin ang Etherscan sa pagpapakita ng mga papasok na transaksyon sa listahan ng mga transaksyon" + "message": "Piliin ito para gamitin ang Etherscan sa pagpapakita ng mga papasok na transaksyon sa listahan ng mga transaksyon", + "description": "$1 is the link to etherscan url and $2 is the link to the privacy policy of consensys APIs" }, "showPermissions": { "message": "Ipakita ang mga pahintulot" diff --git a/app/_locales/pt/messages.json b/app/_locales/pt/messages.json index 04b5e4c3f8b2..585b4c95378b 100644 --- a/app/_locales/pt/messages.json +++ b/app/_locales/pt/messages.json @@ -1737,12 +1737,6 @@ "invalidSeedPhraseCaseSensitive": { "message": "Entrada inválida! A frase secreta de recuperação diferencia maiúsculas e minúsculas." }, - "ipfsGateway": { - "message": "Gateway IPFS" - }, - "ipfsGatewayDescription": { - "message": "Informe o URL do gateway de CID do IPFS para usar com resolução de conteúdo de ENS." - }, "jazzAndBlockies": { "message": "Jazzicons e Blockies são dois estilos diferentes de ícones únicos que ajudam você a identificar uma conta num relance." }, @@ -3085,7 +3079,8 @@ "message": "Mostrar transações recebidas" }, "showIncomingTransactionsDescription": { - "message": "Selecione essa opção para usar o Etherscan e mostrar as transações recebidas na lista de transações" + "message": "Selecione essa opção para usar o Etherscan e mostrar as transações recebidas na lista de transações", + "description": "$1 is the link to etherscan url and $2 is the link to the privacy policy of consensys APIs" }, "showPermissions": { "message": "Mostrar permissões" diff --git a/app/_locales/pt_BR/messages.json b/app/_locales/pt_BR/messages.json index b03ac9d46a04..c900e59f3c33 100644 --- a/app/_locales/pt_BR/messages.json +++ b/app/_locales/pt_BR/messages.json @@ -1357,12 +1357,6 @@ "invalidSeedPhrase": { "message": "Frase de Recuperação Secreta inválida" }, - "ipfsGateway": { - "message": "Gateway IPFS" - }, - "ipfsGatewayDescription": { - "message": "Informe o URL do gateway de CID do IPFS para usar com resolução de conteúdo de ENS." - }, "jsDeliver": { "message": "jsDeliver" }, @@ -2358,7 +2352,8 @@ "message": "Mostrar transações recebidas" }, "showIncomingTransactionsDescription": { - "message": "Selecione essa opção para usar o Etherscan e mostrar as transações recebidas na lista de transações" + "message": "Selecione essa opção para usar o Etherscan e mostrar as transações recebidas na lista de transações", + "description": "$1 is the link to etherscan url and $2 is the link to the privacy policy of consensys APIs" }, "showPermissions": { "message": "Mostrar permissões" diff --git a/app/_locales/ru/messages.json b/app/_locales/ru/messages.json index db808662388c..b02eb8310444 100644 --- a/app/_locales/ru/messages.json +++ b/app/_locales/ru/messages.json @@ -1737,12 +1737,6 @@ "invalidSeedPhraseCaseSensitive": { "message": "Неправильный ввод! Секретная фраза для восстановления чувствительна к регистру." }, - "ipfsGateway": { - "message": "Шлюз IPFS" - }, - "ipfsGatewayDescription": { - "message": "Введите URL-адрес шлюза IPFS CID, который будет использоваться для разрешения содержимого ENS." - }, "jazzAndBlockies": { "message": "«Джазиконы» и «Блокиз» — это два разных стиля уникальных значков, которые помогут вам с первого взгляда идентифицировать свой счет." }, @@ -3085,7 +3079,8 @@ "message": "Показать входящие транзакции" }, "showIncomingTransactionsDescription": { - "message": "Выберите это, чтобы использовать Etherscan для отображения входящих транзакций в списке транзакций" + "message": "Выберите это, чтобы использовать Etherscan для отображения входящих транзакций в списке транзакций", + "description": "$1 is the link to etherscan url and $2 is the link to the privacy policy of consensys APIs" }, "showPermissions": { "message": "Показать разрешения" diff --git a/app/_locales/tl/messages.json b/app/_locales/tl/messages.json index 70cc3252ff96..80f57820d050 100644 --- a/app/_locales/tl/messages.json +++ b/app/_locales/tl/messages.json @@ -1737,12 +1737,6 @@ "invalidSeedPhraseCaseSensitive": { "message": "Di-wastong input! Ang Secret Recovery Phrase ay case sensitive." }, - "ipfsGateway": { - "message": "Gateway na IPFS" - }, - "ipfsGatewayDescription": { - "message": "Ilagay ang URL ng IPFS CID gateway para magamit para sa resolusyon ng content ng ENS." - }, "jazzAndBlockies": { "message": "Ang Jazzicons at Blockies ay dalawang magkaibang istilo ng mga natatanging icon na makakatulong sa iyong matukoy ang account sa isang sulyap." }, @@ -3085,7 +3079,8 @@ "message": "Ipakita ang Mga Papasok na Transaksyon" }, "showIncomingTransactionsDescription": { - "message": "Piliin ito para gamitin ang Etherscan sa pagpapakita ng mga papasok na transaksyon sa listahan ng mga transaksyon" + "message": "Piliin ito para gamitin ang Etherscan sa pagpapakita ng mga papasok na transaksyon sa listahan ng mga transaksyon", + "description": "$1 is the link to etherscan url and $2 is the link to the privacy policy of consensys APIs" }, "showPermissions": { "message": "Ipakita ang mga pahintulot" diff --git a/app/_locales/tr/messages.json b/app/_locales/tr/messages.json index 167c04f26351..075a1ff3925e 100644 --- a/app/_locales/tr/messages.json +++ b/app/_locales/tr/messages.json @@ -1737,12 +1737,6 @@ "invalidSeedPhraseCaseSensitive": { "message": "Giriş geçersiz! Gizli Kurtarma İfadesi büyük/küçük harf duyarlıdır." }, - "ipfsGateway": { - "message": "IPFS Ağ Geçidi" - }, - "ipfsGatewayDescription": { - "message": "ENS içerik çözünürlüğünde kullanmak için IPFS CID ağ geçidi URL adresini girin." - }, "jazzAndBlockies": { "message": "Jazzicons ve Blockies, bir bakışta bir hesabı tanımlamana yardımcı olan iki farklı benzersiz simge stilidir." }, @@ -3085,7 +3079,8 @@ "message": "Gelen İşlemleri Göster" }, "showIncomingTransactionsDescription": { - "message": "Etherscan'in işlemler listesinde gelecek işlemleri göstermesi için bunu seçin" + "message": "Etherscan'in işlemler listesinde gelecek işlemleri göstermesi için bunu seçin", + "description": "$1 is the link to etherscan url and $2 is the link to the privacy policy of consensys APIs" }, "showPermissions": { "message": "İzinleri göster" diff --git a/app/_locales/vi/messages.json b/app/_locales/vi/messages.json index 060ee7544bdd..b30f008d32bc 100644 --- a/app/_locales/vi/messages.json +++ b/app/_locales/vi/messages.json @@ -1737,12 +1737,6 @@ "invalidSeedPhraseCaseSensitive": { "message": "Nội dung nhập không hợp lệ! Cụm từ khôi phục bí mật phân biệt chữ hoa và chữ thường." }, - "ipfsGateway": { - "message": "Cổng kết nối IPFS" - }, - "ipfsGatewayDescription": { - "message": "Nhập URL của cổng kết nối IPFS CID để dùng cho quá trình phân giải nội dung ENS." - }, "jazzAndBlockies": { "message": "Jazzicons và Blockies là hai kiểu biểu tượng độc nhất khác nhau giúp bạn nhận ra tài khoản trong nháy mắt." }, @@ -3085,7 +3079,8 @@ "message": "Hiển thị các giao dịch đến" }, "showIncomingTransactionsDescription": { - "message": "Chọn tùy chọn này nếu bạn muốn dùng Etherscan để hiển thị các giao dịch đến trong danh sách giao dịch" + "message": "Chọn tùy chọn này nếu bạn muốn dùng Etherscan để hiển thị các giao dịch đến trong danh sách giao dịch", + "description": "$1 is the link to etherscan url and $2 is the link to the privacy policy of consensys APIs" }, "showPermissions": { "message": "Hiển thị quyền" diff --git a/app/_locales/zh_CN/messages.json b/app/_locales/zh_CN/messages.json index 91e6fed08f21..e506738c73e4 100644 --- a/app/_locales/zh_CN/messages.json +++ b/app/_locales/zh_CN/messages.json @@ -1737,12 +1737,6 @@ "invalidSeedPhraseCaseSensitive": { "message": "输入无效!助记词须区分大小写。" }, - "ipfsGateway": { - "message": "IPFS 网关" - }, - "ipfsGatewayDescription": { - "message": "输入用于 ENS 内容解析的 IPFS CID 网关的 URL。" - }, "jazzAndBlockies": { "message": "哈希头像是帮助您一眼识别账户的独特图标,有 Jazzicons 和 Blockies 两种不同风格。" }, @@ -3085,7 +3079,8 @@ "message": "显示传入的交易" }, "showIncomingTransactionsDescription": { - "message": "选择此项以使用 Etherscan 在交易列表中显示传入的交易" + "message": "选择此项以使用 Etherscan 在交易列表中显示传入的交易", + "description": "$1 is the link to etherscan url and $2 is the link to the privacy policy of consensys APIs" }, "showPermissions": { "message": "显示权限" diff --git a/app/_locales/zh_TW/messages.json b/app/_locales/zh_TW/messages.json index bb85c6027a1a..a1749a85b2ef 100644 --- a/app/_locales/zh_TW/messages.json +++ b/app/_locales/zh_TW/messages.json @@ -886,9 +886,6 @@ "invalidSeedPhrase": { "message": "無效的助憶詞" }, - "ipfsGatewayDescription": { - "message": "輸入用於解析 ENS 內容的 IPFS CID gateway URL。" - }, "jsonFile": { "message": "JSON 格式檔案", "description": "format for importing an account" @@ -1427,7 +1424,8 @@ "message": "顯示傳入的交易" }, "showIncomingTransactionsDescription": { - "message": "選擇此項來利用 Etherscan 在交易列表裡顯示傳入的交易" + "message": "選擇此項來利用 Etherscan 在交易列表裡顯示傳入的交易", + "description": "$1 is the link to etherscan url and $2 is the link to the privacy policy of consensys APIs" }, "showPermissions": { "message": "顯示權限" diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index 9bacef113977..04eac52eff98 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -130,8 +130,7 @@ export default class PreferencesController { /** * Setter for the `useMultiAccountBalanceChecker` property * - * @param {boolean} val - Whether or not the user wants to fetch balances for - * all accounts that he has added to the MetaMask wallet state. + * @param {boolean} val - Whether or not the user prefers to turn off/on all security settings */ setUseMultiAccountBalanceChecker(val) { this.store.updateState({ useMultiAccountBalanceChecker: val }); diff --git a/app/scripts/lib/util.js b/app/scripts/lib/util.js index 1f19901f10ca..bfd7469d4886 100644 --- a/app/scripts/lib/util.js +++ b/app/scripts/lib/util.js @@ -246,3 +246,10 @@ export function previousValueComparator(comparator, initialValue) { } }; } + +export function addUrlProtocolPrefix(urlString) { + if (!urlString.match(/(^http:\/\/)|(^https:\/\/)/u)) { + return `https://${urlString}`; + } + return urlString; +} diff --git a/shared/constants/metametrics.js b/shared/constants/metametrics.js index f30dc56c2af9..b96e8fdda5bf 100644 --- a/shared/constants/metametrics.js +++ b/shared/constants/metametrics.js @@ -300,6 +300,14 @@ export const EVENT_NAMES = { KEY_EXPORT_CANCELED: 'Key Export Canceled', KEY_EXPORT_REVEALED: 'Key Material Revealed', KEY_EXPORT_COPIED: 'Key Material Copied', + KEY_TOKEN_DETECTION_SELECTED: 'Key Token Detection Selected', + KEY_GLOBAL_SECURITY_TOGGLE_SELECTED: 'Key Global Security/Privacy Settings', + KEY_BALANCE_TOKEN_PRICE_CHECKER: + 'Key Show Balance and Token Price Checker Settings', + KEY_GAS_FEE_ESTIMATION_BUY_SWAP_TOKENS: + 'Key Show Gas Fee Estimation, Buy Crypto and Swap Tokens', + KEY_AUTO_DETECT_TOKENS: 'Key Autodetect tokens', + KEY_BATCH_ACCOUNT_BALANCE_REQUESTS: 'Key Batch account balance requests', METRICS_OPT_IN: 'Metrics Opt In', METRICS_OPT_OUT: 'Metrics Opt Out', NAV_ACCOUNT_MENU_OPENED: 'Account Menu Opened', diff --git a/shared/lib/ui-utils.js b/shared/lib/ui-utils.js index e03ce61e7880..eb3a2143da82 100644 --- a/shared/lib/ui-utils.js +++ b/shared/lib/ui-utils.js @@ -5,3 +5,8 @@ _supportLink = 'https://metamask-flask.zendesk.com/hc'; ///: END:ONLY_INCLUDE_IN export const SUPPORT_LINK = _supportLink; +// TODO make sure these links are correct +export const ETHERSCAN_PRIVACY_LINK = 'https://etherscan.io/privacyPolicy'; +export const CONSENSYS_PRIVACY_LINK = 'https://consensys.net/privacy-policy/'; +export const AUTO_DETECT_TOKEN_LEARN_MORE_LINK = + 'https://consensys.net/privacy-policy/'; diff --git a/test/e2e/fixture-builder.js b/test/e2e/fixture-builder.js index abb25331c155..09fdf77ee67c 100644 --- a/test/e2e/fixture-builder.js +++ b/test/e2e/fixture-builder.js @@ -239,6 +239,7 @@ function defaultFixture() { useNonceField: false, usePhishDetect: true, useTokenDetection: false, + useMultiAccountBalanceChecker: true, }, SmartTransactionsController: { smartTransactionsState: { @@ -352,6 +353,7 @@ function onboardingFixture() { useNonceField: false, usePhishDetect: true, useTokenDetection: false, + useMultiAccountBalanceChecker: true, }, SmartTransactionsController: { smartTransactionsState: { diff --git a/test/e2e/restore/MetaMaskUserData.json b/test/e2e/restore/MetaMaskUserData.json index cb9dffefb50b..48bf95119b92 100644 --- a/test/e2e/restore/MetaMaskUserData.json +++ b/test/e2e/restore/MetaMaskUserData.json @@ -45,6 +45,7 @@ "useNftDetection": false, "useNonceField": false, "usePhishDetect": true, - "useTokenDetection": false + "useTokenDetection": false, + "useMultiAccountBalanceChecker": true } } diff --git a/ui/components/app/whats-new-popup/whats-new-popup.js b/ui/components/app/whats-new-popup/whats-new-popup.js index 5a6b6c52495a..3c28741cb7f8 100644 --- a/ui/components/app/whats-new-popup/whats-new-popup.js +++ b/ui/components/app/whats-new-popup/whats-new-popup.js @@ -49,7 +49,7 @@ function getActionFunctionById(id, history) { }, 10: () => { updateViewedNotifications({ 10: true }); - history.push(`${ADVANCED_ROUTE}#token-description`); + history.push(`${SECURITY_ROUTE}#token-description`); }, 12: () => { updateViewedNotifications({ 12: true }); diff --git a/ui/helpers/constants/settings.js b/ui/helpers/constants/settings.js index 2662abc6de47..2f4bca8a6103 100644 --- a/ui/helpers/constants/settings.js +++ b/ui/helpers/constants/settings.js @@ -118,13 +118,6 @@ export const SETTINGS_CONSTANTS = [ route: `${ADVANCED_ROUTE}#autolock-timer`, icon: 'fas fa-sliders-h', }, - { - tabMessage: (t) => t('advanced'), - sectionMessage: (t) => t('ipfsGateway'), - descriptionMessage: (t) => t('ipfsGatewayDescription'), - route: `${ADVANCED_ROUTE}#ipfs-gateway`, - icon: 'fas fa-sliders-h', - }, { tabMessage: (t) => t('advanced'), sectionMessage: (t) => t('preferredLedgerConnectionType'), @@ -183,13 +176,49 @@ export const SETTINGS_CONSTANTS = [ route: `${SECURITY_ROUTE}#metrametrics`, icon: 'fa fa-lock', }, + { + tabMessage: (t) => t('securityAndPrivacy'), + sectionMessage: (t) => t('enhancedTokenDetection'), + descriptionMessage: (t) => t('enhancedTokenDetectionDescription'), + route: `${SECURITY_ROUTE}#token-description`, + icon: 'fas fa-sliders-h', + }, + { + tabMessage: (t) => t('securityAndPrivacy'), + sectionMessage: (t) => t('chooseYourNetwork'), + descriptionMessage: (t) => t('chooseYourNetworkDescription'), + route: `${SECURITY_ROUTE}#-chose-your-network`, + icon: 'fa fa-lock', + }, + { + tabMessage: (t) => t('securityAndPrivacy'), + sectionMessage: (t) => t('addCustomIPFSGateway'), + descriptionMessage: (t) => t('addCustomIPFSGatewayDescription'), + route: `${SECURITY_ROUTE}#-add-custom-ipfs-gateway`, + icon: 'fa fa-lock', + }, + { + tabMessage: (t) => t('securityAndPrivacy'), + sectionMessage: (t) => t('autoDetectTokens'), + descriptionMessage: (t) => t('autoDetectTokensDescription'), + route: `${SECURITY_ROUTE}#-auto-detect-tokens`, + icon: 'fa fa-lock', + }, { tabMessage: (t) => t('securityAndPrivacy'), sectionMessage: (t) => t('useMultiAccountBalanceChecker'), descriptionMessage: (t) => t('useMultiAccountBalanceCheckerDescription'), - route: `${SECURITY_ROUTE}#multi-account-balance-checker`, + route: `${SECURITY_ROUTE}#-use-milti-account-balance-checker`, icon: 'fa fa-lock', }, + { + tabMessage: (t) => t('securityAndPrivacy'), + sectionMessage: (t) => t('useCollectibleDetection'), + descriptionMessage: (t) => t('useCollectibleDetectionDescription'), + route: `${SECURITY_ROUTE}#autodetect-nfts`, + icon: 'fa fa-flask', + featureFlag: 'COLLECTIBLES_V1', + }, { tabMessage: (t) => t('alerts'), sectionMessage: (t) => t('alertSettingsUnconnectedAccount'), @@ -321,14 +350,6 @@ export const SETTINGS_CONSTANTS = [ icon: 'fa fa-flask', featureFlag: 'COLLECTIBLES_V1', }, - { - tabMessage: (t) => t('experimental'), - sectionMessage: (t) => t('useCollectibleDetection'), - descriptionMessage: (t) => t('useCollectibleDetectionDescription'), - route: `${EXPERIMENTAL_ROUTE}#autodetect-nfts`, - icon: 'fa fa-flask', - featureFlag: 'COLLECTIBLES_V1', - }, { tabMessage: (t) => t('advanced'), sectionMessage: (t) => t('backupUserData'), diff --git a/ui/helpers/utils/settings-search.test.js b/ui/helpers/utils/settings-search.test.js index 4e84eef43f32..f9aeb211aa9a 100644 --- a/ui/helpers/utils/settings-search.test.js +++ b/ui/helpers/utils/settings-search.test.js @@ -159,7 +159,7 @@ describe('Settings Search Utils', () => { }); it('should get good advanced section number', () => { - expect(getNumberOfSettingsInSection(t, t('advanced'))).toStrictEqual(15); + expect(getNumberOfSettingsInSection(t, t('advanced'))).toStrictEqual(14); }); it('should get good contact section number', () => { @@ -169,7 +169,7 @@ describe('Settings Search Utils', () => { it('should get good security & privacy section number', () => { expect( getNumberOfSettingsInSection(t, t('securityAndPrivacy')), - ).toStrictEqual(5); + ).toStrictEqual(9); }); it('should get good alerts section number', () => { diff --git a/ui/pages/import-token/import-token.component.js b/ui/pages/import-token/import-token.component.js index 50445c903f1c..f12b6a221948 100644 --- a/ui/pages/import-token/import-token.component.js +++ b/ui/pages/import-token/import-token.component.js @@ -10,7 +10,7 @@ import { tokenInfoGetter } from '../../helpers/utils/token-util'; import { ADD_COLLECTIBLE_ROUTE, CONFIRM_IMPORT_TOKEN_ROUTE, - ADVANCED_ROUTE, + SECURITY_ROUTE, } from '../../helpers/constants/routes'; import TextField from '../../components/ui/text-field'; import PageContainer from '../../components/ui/page-container'; @@ -445,7 +445,7 @@ class ImportToken extends Component { key="import-token-token-detection-announcement" className="import-token__link" onClick={() => - history.push(`${ADVANCED_ROUTE}#token-description`) + history.push(`${SECURITY_ROUTE}#token-description`) } > {t('inYourSettings')} @@ -588,7 +588,7 @@ class ImportToken extends Component { key="token-detection-announcement" className="import-token__link" onClick={() => - history.push(`${ADVANCED_ROUTE}#token-description`) + history.push(`${SECURITY_ROUTE}#token-description`) } > {t('enableFromSettings')} diff --git a/ui/pages/settings/advanced-tab/advanced-tab.component.js b/ui/pages/settings/advanced-tab/advanced-tab.component.js index 0b3e2a6151bd..0cd79f47695a 100644 --- a/ui/pages/settings/advanced-tab/advanced-tab.component.js +++ b/ui/pages/settings/advanced-tab/advanced-tab.component.js @@ -14,7 +14,6 @@ import { getNumberOfSettingsInSection, handleSettingsRefs, } from '../../../helpers/utils/settings-search'; -import { addUrlProtocolPrefix } from '../../../helpers/utils/ipfs'; import { LEDGER_TRANSPORT_TYPES, @@ -50,15 +49,11 @@ export default class AdvancedTab extends PureComponent { setAutoLockTimeLimit: PropTypes.func.isRequired, setShowFiatConversionOnTestnetsPreference: PropTypes.func.isRequired, setShowTestNetworks: PropTypes.func.isRequired, - setIpfsGateway: PropTypes.func.isRequired, - ipfsGateway: PropTypes.string.isRequired, ledgerTransportType: PropTypes.oneOf(Object.values(LEDGER_TRANSPORT_TYPES)), setLedgerTransportPreference: PropTypes.func.isRequired, setDismissSeedBackUpReminder: PropTypes.func.isRequired, dismissSeedBackUpReminder: PropTypes.bool.isRequired, userHasALedgerAccount: PropTypes.bool.isRequired, - useTokenDetection: PropTypes.bool.isRequired, - setUseTokenDetection: PropTypes.func.isRequired, backupUserData: PropTypes.func.isRequired, restoreUserData: PropTypes.func.isRequired, }; @@ -66,8 +61,6 @@ export default class AdvancedTab extends PureComponent { state = { autoLockTimeLimit: this.props.autoLockTimeLimit, lockTimeError: '', - ipfsGateway: this.props.ipfsGateway, - ipfsGatewayError: '', showLedgerTransportWarning: false, showResultMessage: false, restoreSuccessful: true, @@ -92,37 +85,6 @@ export default class AdvancedTab extends PureComponent { handleSettingsRefs(t, t('advanced'), this.settingsRefs); } - renderMobileSync() { - const { t } = this.context; - const { history } = this.props; - - return ( -
-
- {t('syncWithMobile')} -
-
-
- -
-
-
- ); - } - async getTextFromFile(file) { return new Promise((resolve, reject) => { const reader = new window.FileReader(); @@ -172,68 +134,6 @@ export default class AdvancedTab extends PureComponent { } } - renderRestoreUserData() { - const { t } = this.context; - const { showResultMessage, restoreSuccessful, restoreMessage } = this.state; - - const defaultRestoreMessage = restoreSuccessful - ? t('restoreSuccessful') - : t('restoreFailed'); - const restoreMessageToRender = - restoreMessage === CORRUPT_JSON_FILE - ? t('dataBackupSeemsCorrupt') - : defaultRestoreMessage; - - return ( -
-
- {t('restoreUserData')} - - {t('restoreUserDataDescription')} - -
-
-
- - this.handleFileUpload(e)} - /> -
- {showResultMessage && ( - { - this.setState({ - showResultMessage: false, - restoreSuccessful: true, - restoreMessage: null, - }); - }, - }} - /> - )} -
-
- ); - } - backupUserData = async () => { const { fileName, data } = await this.props.backupUserData(); exportAsFile(fileName, data); @@ -245,29 +145,38 @@ export default class AdvancedTab extends PureComponent { }); }; - renderUserDataBackup() { + renderStateLogs() { const { t } = this.context; + const { displayWarning } = this.props; + return (
- {t('backupUserData')} + {t('stateLogs')} - {t('backupUserDataDescription')} + {t('stateLogsDescription')}
@@ -275,38 +184,30 @@ export default class AdvancedTab extends PureComponent { ); } - renderStateLogs() { + renderMobileSync() { const { t } = this.context; - const { displayWarning } = this.props; + const { history } = this.props; return (
- {t('stateLogs')} - - {t('stateLogsDescription')} - + {t('syncWithMobile')}
@@ -354,27 +255,27 @@ export default class AdvancedTab extends PureComponent { ); } - renderHexDataOptIn() { + renderAdvancedGasInputInline() { const { t } = this.context; - const { sendHexData, setHexDataFeatureFlag } = this.props; + const { advancedInlineGas, setAdvancedInlineGasFeatureFlag } = this.props; return (
- {t('showHexData')} + {t('showAdvancedGasInline')}
- {t('showHexDataDescription')} + {t('showAdvancedGasInlineDescription')}
setHexDataFeatureFlag(!value)} + value={advancedInlineGas} + onToggle={(value) => setAdvancedInlineGasFeatureFlag(!value)} offLabel={t('off')} onLabel={t('on')} /> @@ -384,27 +285,27 @@ export default class AdvancedTab extends PureComponent { ); } - renderAdvancedGasInputInline() { + renderHexDataOptIn() { const { t } = this.context; - const { advancedInlineGas, setAdvancedInlineGasFeatureFlag } = this.props; + const { sendHexData, setHexDataFeatureFlag } = this.props; return (
- {t('showAdvancedGasInline')} + {t('showHexData')}
- {t('showAdvancedGasInlineDescription')} + {t('showHexDataDescription')}
setAdvancedInlineGasFeatureFlag(!value)} + value={sendHexData} + onToggle={(value) => setHexDataFeatureFlag(!value)} offLabel={t('off')} onLabel={t('on')} /> @@ -414,27 +315,30 @@ export default class AdvancedTab extends PureComponent { ); } - renderToggleTestNetworks() { + renderShowConversionInTestnets() { const { t } = this.context; - const { showTestNetworks, setShowTestNetworks } = this.props; + const { showFiatInTestnets, setShowFiatConversionOnTestnetsPreference } = + this.props; return (
- {t('showTestnetNetworks')} + {t('showFiatConversionInTestnets')}
- {t('showTestnetNetworksDescription')} + {t('showFiatConversionInTestnetsDescription')}
setShowTestNetworks(!value)} + value={showFiatInTestnets} + onToggle={(value) => + setShowFiatConversionOnTestnetsPreference(!value) + } offLabel={t('off')} onLabel={t('on')} /> @@ -444,30 +348,27 @@ export default class AdvancedTab extends PureComponent { ); } - renderShowConversionInTestnets() { + renderToggleTestNetworks() { const { t } = this.context; - const { showFiatInTestnets, setShowFiatConversionOnTestnetsPreference } = - this.props; + const { showTestNetworks, setShowTestNetworks } = this.props; return (
- {t('showFiatConversionInTestnets')} + {t('showTestnetNetworks')}
- {t('showFiatConversionInTestnetsDescription')} + {t('showTestnetNetworksDescription')}
- setShowFiatConversionOnTestnetsPreference(!value) - } + value={showTestNetworks} + onToggle={(value) => setShowTestNetworks(!value)} offLabel={t('off')} onLabel={t('on')} /> @@ -507,24 +408,6 @@ export default class AdvancedTab extends PureComponent { ); } - handleLockChange(time) { - const { t } = this.context; - const autoLockTimeLimit = Math.max(Number(time), 0); - - this.setState(() => { - let lockTimeError = ''; - - if (autoLockTimeLimit > 10080) { - lockTimeError = t('lockTimeTooGreat'); - } - - return { - autoLockTimeLimit, - lockTimeError, - }; - }); - } - renderAutoLockTimeLimit() { const { t } = this.context; const { lockTimeError } = this.state; @@ -610,7 +493,7 @@ export default class AdvancedTab extends PureComponent { : LEDGER_TRANSPORT_NAMES.U2F; return ( -
+
{t('preferredLedgerConnectionType')}
@@ -666,151 +549,142 @@ export default class AdvancedTab extends PureComponent { ); } - handleIpfsGatewayChange(url) { - const { t } = this.context; - - this.setState(() => { - let ipfsGatewayError = ''; - - try { - const urlObj = new URL(addUrlProtocolPrefix(url)); - if (!urlObj.host) { - throw new Error(); - } - - // don't allow the use of this gateway - if (urlObj.host === 'gateway.ipfs.io') { - throw new Error('Forbidden gateway'); - } - } catch (error) { - ipfsGatewayError = - error.message === 'Forbidden gateway' - ? t('forbiddenIpfsGateway') - : t('invalidIpfsGateway'); - } - - return { - ipfsGateway: url, - ipfsGatewayError, - }; - }); - } - - handleIpfsGatewaySave() { - const url = new URL(addUrlProtocolPrefix(this.state.ipfsGateway)); - const { host } = url; - - this.props.setIpfsGateway(host); - } - - renderIpfsGatewayControl() { + renderDismissSeedBackupReminderControl() { const { t } = this.context; - const { ipfsGatewayError } = this.state; + const { dismissSeedBackUpReminder, setDismissSeedBackUpReminder } = + this.props; return (
- {t('ipfsGateway')} + {t('dismissReminderField')}
- {t('ipfsGatewayDescription')} + {t('dismissReminderDescriptionField')}
- this.handleIpfsGatewayChange(e.target.value)} - error={ipfsGatewayError} - fullWidth - margin="dense" + setDismissSeedBackUpReminder(!value)} + offLabel={t('off')} + onLabel={t('on')} /> -
); } - renderDismissSeedBackupReminderControl() { + handleLockChange(time) { const { t } = this.context; - const { dismissSeedBackUpReminder, setDismissSeedBackUpReminder } = - this.props; + const autoLockTimeLimit = Math.max(Number(time), 0); + this.setState(() => { + let lockTimeError = ''; + + if (autoLockTimeLimit > 10080) { + lockTimeError = t('lockTimeTooGreat'); + } + + return { + autoLockTimeLimit, + lockTimeError, + }; + }); + } + + renderUserDataBackup() { + const { t } = this.context; return (
- {t('dismissReminderField')} -
- {t('dismissReminderDescriptionField')} -
+ {t('backupUserData')} + + {t('backupUserDataDescription')} +
- setDismissSeedBackUpReminder(!value)} - offLabel={t('off')} - onLabel={t('on')} - /> +
); } - renderTokenDetectionToggle() { + renderRestoreUserData() { const { t } = this.context; - const { useTokenDetection, setUseTokenDetection } = this.props; + const { showResultMessage, restoreSuccessful, restoreMessage } = this.state; + + const defaultRestoreMessage = restoreSuccessful + ? t('restoreSuccessful') + : t('restoreFailed'); + const restoreMessageToRender = + restoreMessage === CORRUPT_JSON_FILE + ? t('dataBackupSeemsCorrupt') + : defaultRestoreMessage; return (
- {t('enhancedTokenDetection')} -
- {t('enhancedTokenDetectionDescription')} -
+ {t('restoreUserData')} + + {t('restoreUserDataDescription')} +
- { - this.context.trackEvent({ - category: EVENT.CATEGORIES.SETTINGS, - event: 'Token Detection', - properties: { - action: 'Token Detection', - legacy_event: true, - }, - }); - setUseTokenDetection(!value); - }} - offLabel={t('off')} - onLabel={t('on')} + + this.handleFileUpload(e)} />
+ {showResultMessage && ( + { + this.setState({ + showResultMessage: false, + restoreSuccessful: true, + restoreMessage: null, + }); + }, + }} + /> + )}
); @@ -828,7 +702,6 @@ export default class AdvancedTab extends PureComponent { {this.renderMobileSync()} {this.renderResetAccount()} {this.renderAdvancedGasInputInline()} - {this.renderTokenDetectionToggle()} {this.renderHexDataOptIn()} {this.renderShowConversionInTestnets()} {this.renderToggleTestNetworks()} @@ -836,7 +709,6 @@ export default class AdvancedTab extends PureComponent { {this.renderAutoLockTimeLimit()} {this.renderUserDataBackup()} {this.renderRestoreUserData()} - {this.renderIpfsGatewayControl()} {notUsingFirefox ? this.renderLedgerLiveControl() : null} {this.renderDismissSeedBackupReminderControl()}
diff --git a/ui/pages/settings/advanced-tab/advanced-tab.component.test.js b/ui/pages/settings/advanced-tab/advanced-tab.component.test.js index fa8d5742dae0..822a0cf67ac3 100644 --- a/ui/pages/settings/advanced-tab/advanced-tab.component.test.js +++ b/ui/pages/settings/advanced-tab/advanced-tab.component.test.js @@ -8,13 +8,11 @@ import AdvancedTab from '.'; const mockSetAutoLockTimeLimit = jest.fn(); const mockSetShowTestNetworks = jest.fn(); -const mockSetUseTokenDetection = jest.fn(); jest.mock('../../../store/actions.js', () => { return { setAutoLockTimeLimit: () => mockSetAutoLockTimeLimit, setShowTestNetworks: () => mockSetShowTestNetworks, - setUseTokenDetection: () => mockSetUseTokenDetection, }; }); @@ -50,20 +48,10 @@ describe('AdvancedTab Component', () => { it('should toggle show test networks', () => { const { queryAllByRole } = renderWithProvider(, mockStore); - const testNetworkToggle = queryAllByRole('checkbox')[4]; + const testNetworkToggle = queryAllByRole('checkbox')[3]; fireEvent.click(testNetworkToggle); expect(mockSetShowTestNetworks).toHaveBeenCalled(); }); - - it('should toggle token detection', () => { - const { queryAllByRole } = renderWithProvider(, mockStore); - - const tokenDetectionToggle = queryAllByRole('checkbox')[1]; - - fireEvent.click(tokenDetectionToggle); - - expect(mockSetUseTokenDetection).toHaveBeenCalled(); - }); }); diff --git a/ui/pages/settings/advanced-tab/advanced-tab.container.js b/ui/pages/settings/advanced-tab/advanced-tab.container.js index 347d9e438542..9826811f6389 100644 --- a/ui/pages/settings/advanced-tab/advanced-tab.container.js +++ b/ui/pages/settings/advanced-tab/advanced-tab.container.js @@ -9,10 +9,8 @@ import { setShowTestNetworks, setAutoLockTimeLimit, setUseNonceField, - setIpfsGateway, setLedgerTransportPreference, setDismissSeedBackUpReminder, - setUseTokenDetection, backupUserData, restoreUserData, } from '../../../store/actions'; @@ -28,10 +26,8 @@ export const mapStateToProps = (state) => { const { featureFlags: { sendHexData, advancedInlineGas } = {}, useNonceField, - ipfsGateway, ledgerTransportType, dismissSeedBackUpReminder, - useTokenDetection, } = metamask; const { showFiatInTestnets, @@ -49,11 +45,9 @@ export const mapStateToProps = (state) => { showTestNetworks, autoLockTimeLimit, useNonceField, - ipfsGateway, ledgerTransportType, dismissSeedBackUpReminder, userHasALedgerAccount, - useTokenDetection, }; }; @@ -78,18 +72,12 @@ export const mapDispatchToProps = (dispatch) => { setAutoLockTimeLimit: (value) => { return dispatch(setAutoLockTimeLimit(value)); }, - setIpfsGateway: (value) => { - return dispatch(setIpfsGateway(value)); - }, setLedgerTransportPreference: (value) => { return dispatch(setLedgerTransportPreference(value)); }, setDismissSeedBackUpReminder: (value) => { return dispatch(setDismissSeedBackUpReminder(value)); }, - setUseTokenDetection: (value) => { - return dispatch(setUseTokenDetection(value)); - }, }; }; diff --git a/ui/pages/settings/experimental-tab/experimental-tab.component.js b/ui/pages/settings/experimental-tab/experimental-tab.component.js index 3f35f7d7f8eb..a74b3802fa11 100644 --- a/ui/pages/settings/experimental-tab/experimental-tab.component.js +++ b/ui/pages/settings/experimental-tab/experimental-tab.component.js @@ -47,57 +47,6 @@ export default class ExperimentalTab extends PureComponent { handleSettingsRefs(t, t('experimental'), this.settingsRefs); } - renderCollectibleDetectionToggle() { - if (!process.env.COLLECTIBLES_V1) { - return null; - } - - const { t } = this.context; - const { - useNftDetection, - setUseNftDetection, - openSeaEnabled, - setOpenSeaEnabled, - } = this.props; - - return ( -
-
- {t('useCollectibleDetection')} -
- {t('useCollectibleDetectionDescription')} -
-
-
-
- { - this.context.trackEvent({ - category: EVENT.CATEGORIES.SETTINGS, - event: 'Collectible Detection', - properties: { - action: 'Collectible Detection', - legacy_event: true, - }, - }); - if (!value && !openSeaEnabled) { - setOpenSeaEnabled(!value); - } - setUseNftDetection(!value); - }} - offLabel={t('off')} - onLabel={t('on')} - /> -
-
-
- ); - } - renderOpenSeaEnabledToggle() { if (!process.env.COLLECTIBLES_V1) { return null; @@ -278,8 +227,6 @@ export default class ExperimentalTab extends PureComponent { this.renderTransactionSecurityCheckToggle()} {this.renderImprovedTokenAllowanceToggle()} {this.renderOpenSeaEnabledToggle()} - {this.renderCollectibleDetectionToggle()} - {this.renderEIP1559V2EnabledToggle()}
); } diff --git a/ui/pages/settings/index.scss b/ui/pages/settings/index.scss index 13ce61c26fbf..4312200800c2 100644 --- a/ui/pages/settings/index.scss +++ b/ui/pages/settings/index.scss @@ -12,6 +12,10 @@ display: flex; flex-flow: column nowrap; + &__content-padded { + padding: 16px; + } + &__error-text { @include H7; @@ -194,6 +198,18 @@ } } + &__security-tab-sub-header { + font-weight: 500; + font-size: 16px; + color: var(--color-icon-alternative); + + &__bold { + font-weight: 700; + font-size: 18px; + color: var(--color-text-default); + } + } + &__back-button { display: none; @@ -275,6 +291,8 @@ display: flex; flex-direction: column; margin-bottom: 20px; + font-size: 16px; + font-weight: 500; @include screen-sm-max { height: initial; @@ -327,6 +345,8 @@ margin-top: 8px; margin-bottom: 12px; color: var(--color-text-default); + font-size: 14px; + font-weight: 400; } } @@ -334,10 +354,16 @@ text-transform: capitalize; } + &__content-unordered-list { + padding-left: 2.5rem; + margin-top: 2.5rem; + list-style: disc; + } + &__content-description { @include H6; - color: var(--color-text-default); + color: var(--color-text-alternative); padding-top: 5px; a { diff --git a/ui/pages/settings/security-tab/__snapshots__/security-tab.test.js.snap b/ui/pages/settings/security-tab/__snapshots__/security-tab.test.js.snap index f42c8afbe7ad..8e8ad57636bf 100644 --- a/ui/pages/settings/security-tab/__snapshots__/security-tab.test.js.snap +++ b/ui/pages/settings/security-tab/__snapshots__/security-tab.test.js.snap @@ -5,239 +5,476 @@ exports[`Security Tab should match snapshot 1`] = `
+ + Security +
- - Reveal Secret Recovery Phrase - -
-
- + +
+
+
+ +
+ + Privacy + +
+ + Alerts + +
- - Show incoming transactions -
- Select this to use Etherscan to show incoming transactions in the transactions list + + Use phishing detection + +
+ Display a warning for phishing domains targeting Ethereum users +
-
-
-