Fix a hash displayed in tooltip when signing arbitrary data (#6283)
* Allow connections from firefox extension. * Displaying actual data that will be signed on hover. * Display a tooltip. * Revert "Allow connections from firefox extension." This reverts commit d3323b76fe28564c2366ceec3d891de19884192f.
This commit is contained in:
parent
604ea5d684
commit
b5b6e3dd2a
@ -75,7 +75,10 @@ export function bytesToAscii (bytes) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function asciiToHex (string) {
|
export function asciiToHex (string) {
|
||||||
return '0x' + string.split('').map((s) => s.charCodeAt(0).toString(16)).join('');
|
return '0x' + string.split('')
|
||||||
|
.map(s => s.charCodeAt(0))
|
||||||
|
.map(s => s < 0x10 ? '0' + s.toString(16) : s.toString(16))
|
||||||
|
.join('');
|
||||||
}
|
}
|
||||||
|
|
||||||
export function padRight (input, length) {
|
export function padRight (input, length) {
|
||||||
|
@ -67,6 +67,7 @@ describe('api/util/format', () => {
|
|||||||
|
|
||||||
it('correctly converts a non-empty string', () => {
|
it('correctly converts a non-empty string', () => {
|
||||||
expect(asciiToHex('abc')).to.equal('0x616263');
|
expect(asciiToHex('abc')).to.equal('0x616263');
|
||||||
|
expect(asciiToHex('a\nb')).to.equal('0x610a62');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
import { isAddress as isAddressValid, toChecksumAddress } from '../../abi/util/address';
|
import { isAddress as isAddressValid, toChecksumAddress } from '../../abi/util/address';
|
||||||
import { abiDecode, decodeCallData, decodeMethodInput, methodToAbi } from './decode';
|
import { abiDecode, decodeCallData, decodeMethodInput, methodToAbi } from './decode';
|
||||||
import { abiEncode, abiUnencode, abiSignature, encodeMethodCallAbi } from './encode';
|
import { abiEncode, abiUnencode, abiSignature, encodeMethodCallAbi } from './encode';
|
||||||
import { bytesToHex, hexToAscii, asciiToHex, cleanupValue } from './format';
|
import { bytesToHex, hexToAscii, hexToBytes, asciiToHex, cleanupValue } from './format';
|
||||||
import { fromWei, toWei } from './wei';
|
import { fromWei, toWei } from './wei';
|
||||||
import { sha3 } from './sha3';
|
import { sha3 } from './sha3';
|
||||||
import { isArray, isFunction, isHex, isInstanceOf, isString } from './types';
|
import { isArray, isFunction, isHex, isInstanceOf, isString } from './types';
|
||||||
@ -37,6 +37,7 @@ export default {
|
|||||||
isString,
|
isString,
|
||||||
bytesToHex,
|
bytesToHex,
|
||||||
hexToAscii,
|
hexToAscii,
|
||||||
|
hexToBytes,
|
||||||
asciiToHex,
|
asciiToHex,
|
||||||
createIdentityImg,
|
createIdentityImg,
|
||||||
decodeCallData,
|
decodeCallData,
|
||||||
|
@ -18,6 +18,7 @@ import { observer } from 'mobx-react';
|
|||||||
import React, { Component, PropTypes } from 'react';
|
import React, { Component, PropTypes } from 'react';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
import ReactTooltip from 'react-tooltip';
|
||||||
|
|
||||||
import HardwareStore from '~/mobx/hardwareStore';
|
import HardwareStore from '~/mobx/hardwareStore';
|
||||||
|
|
||||||
@ -70,6 +71,10 @@ class SignRequest extends Component {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
state = {
|
||||||
|
hashToSign: null
|
||||||
|
};
|
||||||
|
|
||||||
hardwareStore = HardwareStore.get(this.context.api);
|
hardwareStore = HardwareStore.get(this.context.api);
|
||||||
|
|
||||||
componentWillMount () {
|
componentWillMount () {
|
||||||
@ -78,6 +83,25 @@ class SignRequest extends Component {
|
|||||||
signerStore.fetchBalance(address);
|
signerStore.fetchBalance(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidMount () {
|
||||||
|
this.computeHashToSign(this.props.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillReceiveProps (nextProps) {
|
||||||
|
if (this.props.data !== nextProps.data) {
|
||||||
|
this.computeHashToSign(nextProps.data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
computeHashToSign (data) {
|
||||||
|
const { sha3, hexToBytes, asciiToHex } = this.context.api.util;
|
||||||
|
const bytes = hexToBytes(data);
|
||||||
|
const message = hexToBytes(asciiToHex(`\x19Ethereum Signed Message:\n${bytes.length}`));
|
||||||
|
const hashToSign = sha3(message.concat(bytes));
|
||||||
|
|
||||||
|
this.setState({ hashToSign });
|
||||||
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { className } = this.props;
|
const { className } = this.props;
|
||||||
|
|
||||||
@ -113,6 +137,7 @@ class SignRequest extends Component {
|
|||||||
renderDetails () {
|
renderDetails () {
|
||||||
const { api } = this.context;
|
const { api } = this.context;
|
||||||
const { address, data, netVersion, origin, signerStore } = this.props;
|
const { address, data, netVersion, origin, signerStore } = this.props;
|
||||||
|
const { hashToSign } = this.state;
|
||||||
const { balances, externalLink } = signerStore;
|
const { balances, externalLink } = signerStore;
|
||||||
|
|
||||||
const balance = balances[address];
|
const balance = balances[address];
|
||||||
@ -121,6 +146,20 @@ class SignRequest extends Component {
|
|||||||
return <div />;
|
return <div />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const tooltip = [
|
||||||
|
<FormattedMessage
|
||||||
|
id='signer.signRequest.tooltip.hash'
|
||||||
|
defaultMessage='Hash to be signed: {hashToSign}'
|
||||||
|
values={ { hashToSign } }
|
||||||
|
/>,
|
||||||
|
<br />,
|
||||||
|
<FormattedMessage
|
||||||
|
id='signer.signRequest.tooltip.data'
|
||||||
|
defaultMessage='Data: {data}'
|
||||||
|
values={ { data } }
|
||||||
|
/>
|
||||||
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={ styles.signDetails }>
|
<div className={ styles.signDetails }>
|
||||||
<div className={ styles.address }>
|
<div className={ styles.address }>
|
||||||
@ -133,7 +172,16 @@ class SignRequest extends Component {
|
|||||||
/>
|
/>
|
||||||
<RequestOrigin origin={ origin } />
|
<RequestOrigin origin={ origin } />
|
||||||
</div>
|
</div>
|
||||||
<div className={ styles.info } title={ api.util.sha3(data) }>
|
<ReactTooltip id={ `signRequest-${hashToSign}` }>
|
||||||
|
{ tooltip }
|
||||||
|
</ReactTooltip>
|
||||||
|
<div
|
||||||
|
className={ styles.info }
|
||||||
|
data-effect='solid'
|
||||||
|
data-for={ `signRequest-${hashToSign}` }
|
||||||
|
data-place='top'
|
||||||
|
data-tip
|
||||||
|
>
|
||||||
<p>
|
<p>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='signer.signRequest.request'
|
id='signer.signRequest.request'
|
||||||
|
@ -53,7 +53,14 @@ function render () {
|
|||||||
<SignRequest signerStore={ signerStore } />,
|
<SignRequest signerStore={ signerStore } />,
|
||||||
{
|
{
|
||||||
context: {
|
context: {
|
||||||
store: reduxStore
|
store: reduxStore,
|
||||||
|
api: {
|
||||||
|
util: {
|
||||||
|
sha3: (x) => x,
|
||||||
|
hexToBytes: (x) => x,
|
||||||
|
asciiToHex: (x) => x
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
).find('SignRequest').shallow();
|
).find('SignRequest').shallow();
|
||||||
@ -61,7 +68,7 @@ function render () {
|
|||||||
return component;
|
return component;
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('views/Signer/components/SignRequest', () => {
|
describe.only('views/Signer/components/SignRequest', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
render();
|
render();
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user