diff --git a/CHANGELOG.md b/CHANGELOG.md index c515547ab..3b304eccf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [10.9.3] +### Fixed +- Allow for scrolling when sign type data message is too long ([#13642](https://github.com/MetaMask/metamask-extension/pull/13642)) + - Require a scroll through of message before allowing user signature + ## [10.9.2] ### Fixed - Prevent errors on the swaps "View Quote" screen that can occur if the swaps API returns incorrect refund and max gas fees on some test networks ([#13511](https://github.com/MetaMask/metamask-extension/pull/13511)) @@ -2697,7 +2702,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.9.2...HEAD +[Unreleased]: https://github.com/MetaMask/metamask-extension/compare/v10.9.3...HEAD +[10.9.3]: https://github.com/MetaMask/metamask-extension/compare/v10.9.2...v10.9.3 [10.9.2]: https://github.com/MetaMask/metamask-extension/compare/v10.9.1...v10.9.2 [10.9.1]: https://github.com/MetaMask/metamask-extension/compare/v10.9.0...v10.9.1 [10.9.0]: https://github.com/MetaMask/metamask-extension/compare/v10.8.2...v10.9.0 diff --git a/package.json b/package.json index 2555ddaf8..2e5e8b5da 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "metamask-crx", - "version": "10.9.2", + "version": "10.9.3", "private": true, "repository": { "type": "git", @@ -85,6 +85,7 @@ "3box/ipfs/prometheus-gc-stats/gc-stats/node-pre-gyp/tar": "^6.1.2", "3box/**/libp2p-crypto/node-forge": "^1.0.0", "3box/**/libp2p-keychain/node-forge": "^1.0.0", + "3box/ipfs/libp2p-webrtc-star/socket.io/engine.io": "^4.0.0", "analytics-node/axios": "^0.21.2", "analytics-node/axios/follow-redirects": "^1.14.7", "ganache-core/lodash": "^4.17.21", diff --git a/test/e2e/tests/signature-request.spec.js b/test/e2e/tests/signature-request.spec.js index bf2a547e2..6260f699d 100644 --- a/test/e2e/tests/signature-request.spec.js +++ b/test/e2e/tests/signature-request.spec.js @@ -1,5 +1,5 @@ const { strict: assert } = require('assert'); -const { withFixtures } = require('../helpers'); +const { withFixtures, regularDelayMs } = require('../helpers'); describe('Signature Request', function () { it('can initiate and confirm a Signature Request', async function () { @@ -59,6 +59,10 @@ describe('Signature Request', function () { ); // Approve signing typed data + await driver.clickElement( + '[data-testid="signature-request-scroll-button"]', + ); + await driver.delay(regularDelayMs); await driver.clickElement({ text: 'Sign', tag: 'button' }, 10000); await driver.waitUntilXWindowHandles(2); windowHandles = await driver.getAllWindowHandles(); diff --git a/ui/components/app/signature-request/signature-request-footer/index.scss b/ui/components/app/signature-request/signature-request-footer/index.scss index b1470d3e3..e679bef43 100644 --- a/ui/components/app/signature-request/signature-request-footer/index.scss +++ b/ui/components/app/signature-request/signature-request-footer/index.scss @@ -9,10 +9,16 @@ } button:first-child { - margin-left: 1rem; + flex: 1 1 100%; + padding: 0; } button:last-child { + flex: 1 1 100%; margin-right: 1rem; } + + &__tooltip { + display: flex; + } } diff --git a/ui/components/app/signature-request/signature-request-message/index.scss b/ui/components/app/signature-request/signature-request-message/index.scss index 3652addd1..14f8d4f39 100644 --- a/ui/components/app/signature-request/signature-request-message/index.scss +++ b/ui/components/app/signature-request/signature-request-message/index.scss @@ -1,7 +1,9 @@ .signature-request-message { flex: 1 60%; display: flex; + max-height: 250px; flex-direction: column; + position: relative; &__title { @include H6; @@ -56,4 +58,16 @@ &--node-leaf { display: flex; } + + &__scroll-button { + display: flex; + align-items: center; + justify-content: center; + background-color: var(--Grey-500); + position: absolute; + right: 24px; + bottom: 12px; + border-radius: 50%; + cursor: pointer; + } } diff --git a/ui/components/app/signature-request/signature-request-message/signature-request-message.component.js b/ui/components/app/signature-request/signature-request-message/signature-request-message.component.js index ca1056718..3c186f4c5 100644 --- a/ui/components/app/signature-request/signature-request-message/signature-request-message.component.js +++ b/ui/components/app/signature-request/signature-request-message/signature-request-message.component.js @@ -1,16 +1,41 @@ import React, { PureComponent } from 'react'; import PropTypes from 'prop-types'; +import { debounce } from 'lodash'; import classnames from 'classnames'; export default class SignatureRequestMessage extends PureComponent { static propTypes = { data: PropTypes.object.isRequired, + onMessageScrolled: PropTypes.func, + setMessageRootRef: PropTypes.func, + messageRootRef: PropTypes.object, + messageIsScrollable: PropTypes.bool, }; static contextTypes = { t: PropTypes.func, }; + state = { + messageIsScrolled: false, + }; + + setMessageIsScrolled = () => { + if (!this.props.messageRootRef || this.state.messageIsScrolled) { + return; + } + + const { scrollTop, offsetHeight, scrollHeight } = this.props.messageRootRef; + const isAtBottom = scrollTop + offsetHeight >= scrollHeight; + + if (isAtBottom) { + this.setState({ messageIsScrolled: true }); + this.props.onMessageScrolled(); + } + }; + + onScroll = debounce(this.setMessageIsScrolled, 25); + renderNode(data) { return (
@@ -38,15 +63,43 @@ export default class SignatureRequestMessage extends PureComponent { ); } + renderScrollButton() { + return ( +
{ + this.setState({ messageIsScrolled: true }); + this.props.onMessageScrolled(); + this.props.messageRootRef.scrollTo( + 0, + this.props.messageRootRef.scrollHeight, + ); + }} + className="signature-request-message__scroll-button" + data-testid="signature-request-scroll-button" + > + {this.context.t('scrollDown')} +
+ ); + } + render() { - const { data } = this.props; + const { data, messageIsScrollable } = this.props; return ( -
+
+ {messageIsScrollable ? this.renderScrollButton() : null}
{this.context.t('signatureRequest1')}
-
+
{this.renderNode(data)}
diff --git a/ui/components/app/signature-request/signature-request.component.js b/ui/components/app/signature-request/signature-request.component.js index c7ff1a004..164221e16 100644 --- a/ui/components/app/signature-request/signature-request.component.js +++ b/ui/components/app/signature-request/signature-request.component.js @@ -44,6 +44,14 @@ export default class SignatureRequest extends PureComponent { metricsEvent: PropTypes.func, }; + state = { + hasScrolledMessage: false, + }; + + setMessageRootRef(ref) { + this.messageRootRef = ref; + } + formatWallet(wallet) { return `${wallet.slice(0, 8)}...${wallet.slice( wallet.length - 8, @@ -97,6 +105,9 @@ export default class SignatureRequest extends PureComponent { }); }; + const messageIsScrollable = + this.messageRootRef?.scrollHeight > this.messageRootRef?.clientHeight; + return (
@@ -124,11 +135,20 @@ export default class SignatureRequest extends PureComponent {
) : null} - + this.setState({ hasScrolledMessage: true })} + setMessageRootRef={this.setMessageRootRef.bind(this)} + messageRootRef={this.messageRootRef} + messageIsScrollable={messageIsScrollable} + />
); diff --git a/yarn.lock b/yarn.lock index 1fd77eb86..5e9328639 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5091,6 +5091,11 @@ acorn-walk@^7.0.0, acorn-walk@^7.1.1, acorn-walk@^7.2.0: resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== +acorn-walk@^8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" + integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== + acorn@^3.0.4: version "3.3.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" @@ -5111,10 +5116,10 @@ acorn@^7.0.0, acorn@^7.1.1, acorn@^7.4.0, acorn@^7.4.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -acorn@^8.2.4: - version "8.5.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.5.0.tgz#4512ccb99b3698c752591e9bb4472e38ad43cee2" - integrity sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q== +acorn@^8.2.4, acorn@^8.7.0: + version "8.7.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf" + integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ== addons-linter@1.14.0: version "1.14.0" @@ -9020,7 +9025,7 @@ core-util-is@1.0.2, core-util-is@~1.0.0: resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= -cors@^2.8.1: +cors@^2.8.1, cors@~2.8.5: version "2.8.5" resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== @@ -9512,10 +9517,10 @@ debug@3.2.6, debug@3.X, debug@^3.0.0, debug@^3.1.0, debug@^3.2.6: dependencies: ms "^2.1.1" -debug@4, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0, debug@^4.3.1, debug@^4.3.2: - version "4.3.2" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" - integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== +debug@4, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0, debug@^4.3.1, debug@^4.3.2, debug@~4.3.1: + version "4.3.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" + integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== dependencies: ms "2.1.2" @@ -10582,16 +10587,24 @@ engine.io-parser@~2.2.0: blob "0.0.5" has-binary2 "~1.0.2" -engine.io@~3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-3.5.0.tgz#9d6b985c8a39b1fe87cd91eb014de0552259821b" - integrity sha512-21HlvPUKaitDGE4GXNtQ7PLP0Sz4aWLddMPw2VTyFz1FVZqu/kZsJUO8WNpKuE/OCL7nkfRaOui2ZCJloGznGA== +engine.io-parser@~4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-4.0.3.tgz#83d3a17acfd4226f19e721bb22a1ee8f7662d2f6" + integrity sha512-xEAAY0msNnESNPc00e19y5heTPX4y/TJ36gr8t1voOaNmTojP9b3oK3BbJLFufW2XFPQaaijpFewm2g2Um3uqA== + dependencies: + base64-arraybuffer "0.1.4" + +engine.io@^4.0.0, engine.io@~3.5.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-4.1.2.tgz#f96ceb56d4b39cc7ca5bd29a20e9c99c1ad1a765" + integrity sha512-t5z6zjXuVLhXDMiFJPYsPOWEER8B0tIsD3ETgw19S1yg9zryvUfY3Vhtk3Gf4sihw/bQGIqQ//gjvVlu+Ca0bQ== dependencies: accepts "~1.3.4" base64id "2.0.0" cookie "~0.4.1" - debug "~4.1.0" - engine.io-parser "~2.2.0" + cors "~2.8.5" + debug "~4.3.1" + engine.io-parser "~4.0.0" ws "~7.4.2" enhanced-resolve@^4.5.0: @@ -13028,9 +13041,9 @@ fnv1a@^1.0.1: integrity sha1-kV4tbQI8Q9UiStn20qPEFW9XEvU= follow-redirects@^1.14.0, follow-redirects@^1.14.7: - version "1.14.7" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.7.tgz#2004c02eb9436eee9a21446a6477debf17e81685" - integrity sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ== + version "1.14.8" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.8.tgz#016996fb9a11a100566398b1c6839337d7bfa8fc" + integrity sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA== for-each@^0.3.3, for-each@~0.3.3: version "0.3.3" @@ -28187,9 +28200,12 @@ vm-browserify@^1.0.0, vm-browserify@^1.0.1: integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== vm2@^3.9.3: - version "3.9.5" - resolved "https://registry.yarnpkg.com/vm2/-/vm2-3.9.5.tgz#5288044860b4bbace443101fcd3bddb2a0aa2496" - integrity sha512-LuCAHZN75H9tdrAiLFf030oW7nJV5xwNMuk1ymOZwopmuK3d2H4L1Kv4+GFHgarKiLfXXLFU+7LDABHnwOkWng== + version "3.9.7" + resolved "https://registry.yarnpkg.com/vm2/-/vm2-3.9.7.tgz#bb87aa677c97c61e23a6cb6547e44e990517a6f6" + integrity sha512-g/GZ7V0Mlmch3eDVOATvAXr1GsJNg6kQ5PjvYy3HbJMCRn5slNbo/u73Uy7r5yUej1cRa3ZjtoVwcWSQuQ/fow== + dependencies: + acorn "^8.7.0" + acorn-walk "^8.2.0" w3c-hr-time@^1.0.2: version "1.0.2"