Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V7.7.5 Upstream Changes #124

Merged
merged 12 commits into from Feb 25, 2020

Validate custom spend limit (#7920)

The custom spend limit was previously not validated. It did have a
minimum of zero set, but this didn't have any affect (that minimum is
used for form constraint validation, and this field wasn't in a form).
The field was never checked to ensure the contents didn't exceed the
maximum.

The field is now checked for values that exceed the maximum, and
invalid values in general (including negative values).

The parameters to the `showEditApprovalPermissionModal` were also
alphabetized to make them easier to read. In the course of doing this,
I noticed that the origin was missing from one of the calls. This was
responsible for the modal saying "Spend limit requested by undefined"
when clicking "Edit" under the transaction details. This has been
fixed.
  • Loading branch information
Gudahtt authored and ryanml committed Jan 29, 2020
commit 1a61f150927869f611d1846388bc6c0ecc47421d
@@ -1261,6 +1261,12 @@
"message": "Spend limit requested by $1",
"description": "Origin of the site requesting the spend limit"
},
"spendLimitTooLarge": {
"message": "Spend limit too large"
},
"spendLimitInvalid": {
"message": "Spend limit invalid; must be a positive number"
},
"switchNetworks": {
"message": "Switch Networks"
},
@@ -1,21 +1,26 @@
import React, { PureComponent } from 'react'
import PropTypes from 'prop-types'
import log from 'loglevel'
import Modal from '../../modal'
import Identicon from '../../../ui/identicon'
import TextField from '../../../ui/text-field'
import { calcTokenAmount } from '../../../../helpers/utils/token-util'
import classnames from 'classnames'
import BigNumber from 'bignumber.js'

const MAX_UNSIGNED_256_INT = new BigNumber(2).pow(256).minus(1).toString(10)

export default class EditApprovalPermission extends PureComponent {
static propTypes = {
decimals: PropTypes.number,
hideModal: PropTypes.func.isRequired,
selectedIdentity: PropTypes.object,
tokenAmount: PropTypes.string,
customTokenAmount: PropTypes.string,
tokenSymbol: PropTypes.string,
tokenBalance: PropTypes.string,
setCustomAmount: PropTypes.func,
origin: PropTypes.string,
origin: PropTypes.string.isRequired,
}

static contextTypes = {
@@ -27,7 +32,7 @@ export default class EditApprovalPermission extends PureComponent {
selectedOptionIsUnlimited: !this.props.customTokenAmount,
}

renderModalContent () {
renderModalContent (error) {
const { t } = this.context
const {
hideModal,
@@ -128,7 +133,6 @@ export default class EditApprovalPermission extends PureComponent {
<div className="edit-approval-permission__edit-section__option-input" >
<TextField
type="number"
min="0"
placeholder={ `${Number(customTokenAmount || tokenAmount)} ${tokenSymbol}` }
onChange={(event) => {
this.setState({ customSpendLimit: event.target.value })
@@ -139,6 +143,7 @@ export default class EditApprovalPermission extends PureComponent {
fullWidth
margin="dense"
value={ this.state.customSpendLimit }
error={error}
/>
</div>
</div>
@@ -148,10 +153,44 @@ export default class EditApprovalPermission extends PureComponent {
)
}

validateSpendLimit () {
const { t } = this.context
const { decimals } = this.props
const { selectedOptionIsUnlimited, customSpendLimit } = this.state

if (selectedOptionIsUnlimited || !customSpendLimit) {
return
}

let customSpendLimitNumber
try {
customSpendLimitNumber = new BigNumber(customSpendLimit)
} catch (error) {
log.debug(`Error converting '${customSpendLimit}' to BigNumber:`, error)
return t('spendLimitInvalid')
}

if (customSpendLimitNumber.isNegative()) {
return t('spendLimitInvalid')
}

const maxTokenAmount = calcTokenAmount(MAX_UNSIGNED_256_INT, decimals)
if (customSpendLimitNumber.greaterThan(maxTokenAmount)) {
return t('spendLimitTooLarge')
}
}

render () {
const { t } = this.context
const { setCustomAmount, hideModal, customTokenAmount } = this.props
const { selectedOptionIsUnlimited, customSpendLimit } = this.state

const error = this.validateSpendLimit()
const disabled = Boolean(
(customSpendLimit === customTokenAmount && !selectedOptionIsUnlimited) ||
error
)

return (
<Modal
onSubmit={() => {
@@ -162,9 +201,9 @@ export default class EditApprovalPermission extends PureComponent {
submitType="primary"
contentClass="edit-approval-permission-modal-content"
containerClass="edit-approval-permission-modal-container"
submitDisabled={ (customSpendLimit === customTokenAmount) && !selectedOptionIsUnlimited }
submitDisabled={disabled}
>
{ this.renderModalContent() }
{ this.renderModalContent(error) }
</Modal>
)
}
@@ -15,6 +15,7 @@ export default class ConfirmApproveContent extends Component {
static propTypes = {
amount: PropTypes.string,
txFeeTotal: PropTypes.string,
decimals: PropTypes.number,
tokenAmount: PropTypes.string,
customTokenAmount: PropTypes.string,
tokenSymbol: PropTypes.string,
@@ -124,6 +125,7 @@ export default class ConfirmApproveContent extends Component {
render () {
const { t } = this.context
const {
decimals,
siteImage,
tokenAmount,
customTokenAmount,
@@ -159,7 +161,15 @@ export default class ConfirmApproveContent extends Component {
>
<div
className="confirm-approve-content__medium-link-text cursor-pointer"
onClick={() => showEditApprovalPermissionModal({ customTokenAmount, tokenAmount, tokenSymbol, setCustomAmount, tokenBalance, origin })}
onClick={() => showEditApprovalPermissionModal({
customTokenAmount,
decimals,
origin,
setCustomAmount,
tokenAmount,
tokenSymbol,
tokenBalance,
})}
>
{ t('editPermission') }
</div>
@@ -201,10 +211,12 @@ export default class ConfirmApproveContent extends Component {
showEdit: true,
onEditClick: () => showEditApprovalPermissionModal({
customTokenAmount,
decimals,
origin,
setCustomAmount,
tokenAmount,
tokenSymbol,
tokenBalance,
setCustomAmount,
}),
})}
</div>
@@ -86,6 +86,7 @@ export default class ConfirmApprove extends Component {
showAccountInHeader
title={tokensText}
contentComponent={<ConfirmApproveContent
decimals={decimals}
siteImage={siteImage}
tokenAddress={tokenAddress}
setCustomAmount={(newAmount) => {
@@ -76,20 +76,22 @@ const mapDispatchToProps = (dispatch) => {
return {
showCustomizeGasModal: (txData) => dispatch(showModal({ name: 'CUSTOMIZE_GAS', txData })),
showEditApprovalPermissionModal: ({
tokenAmount,
customTokenAmount,
tokenSymbol,
tokenBalance,
setCustomAmount,
decimals,
origin,
setCustomAmount,
tokenAmount,
tokenBalance,
tokenSymbol,
}) => dispatch(showModal({
name: 'EDIT_APPROVAL_PERMISSION',
tokenAmount,
customTokenAmount,
tokenSymbol,
tokenBalance,
setCustomAmount,
decimals,
origin,
setCustomAmount,
tokenAmount,
tokenBalance,
tokenSymbol,
})),
}
}
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.