Add decryption to the UI (in the Signer) (#5422)
* Add decryption to the UI in signer + Fix Signing style * Proper out format function for singing methods * name
This commit is contained in:
parent
20d4e7139f
commit
0aaf236ad1
@ -216,6 +216,8 @@ export function outSignerRequest (request) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'payload':
|
case 'payload':
|
||||||
|
request[key].decrypt = outSigningPayload(request[key].decrypt);
|
||||||
|
request[key].sign = outSigningPayload(request[key].sign);
|
||||||
request[key].signTransaction = outTransaction(request[key].signTransaction);
|
request[key].signTransaction = outTransaction(request[key].signTransaction);
|
||||||
request[key].sendTransaction = outTransaction(request[key].sendTransaction);
|
request[key].sendTransaction = outTransaction(request[key].sendTransaction);
|
||||||
break;
|
break;
|
||||||
@ -296,6 +298,20 @@ export function outTransaction (tx) {
|
|||||||
return tx;
|
return tx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function outSigningPayload (payload) {
|
||||||
|
if (payload) {
|
||||||
|
Object.keys(payload).forEach((key) => {
|
||||||
|
switch (key) {
|
||||||
|
case 'address':
|
||||||
|
payload[key] = outAddress(payload[key]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return payload;
|
||||||
|
}
|
||||||
|
|
||||||
export function outTrace (trace) {
|
export function outTrace (trace) {
|
||||||
if (trace) {
|
if (trace) {
|
||||||
if (trace.action) {
|
if (trace.action) {
|
||||||
|
183
js/src/views/Signer/components/DecryptRequest/decryptRequest.js
Normal file
183
js/src/views/Signer/components/DecryptRequest/decryptRequest.js
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import { observer } from 'mobx-react';
|
||||||
|
import React, { Component, PropTypes } from 'react';
|
||||||
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
|
import Account from '../Account';
|
||||||
|
import TransactionPendingForm from '../TransactionPendingForm';
|
||||||
|
import RequestOrigin from '../RequestOrigin';
|
||||||
|
|
||||||
|
import styles from '../SignRequest/signRequest.css';
|
||||||
|
|
||||||
|
@observer
|
||||||
|
class DecryptRequest extends Component {
|
||||||
|
static contextTypes = {
|
||||||
|
api: PropTypes.object
|
||||||
|
};
|
||||||
|
|
||||||
|
static propTypes = {
|
||||||
|
accounts: PropTypes.object.isRequired,
|
||||||
|
address: PropTypes.string.isRequired,
|
||||||
|
data: PropTypes.string.isRequired,
|
||||||
|
id: PropTypes.object.isRequired,
|
||||||
|
isFinished: PropTypes.bool.isRequired,
|
||||||
|
netVersion: PropTypes.string.isRequired,
|
||||||
|
signerStore: PropTypes.object.isRequired,
|
||||||
|
|
||||||
|
className: PropTypes.string,
|
||||||
|
focus: PropTypes.bool,
|
||||||
|
isSending: PropTypes.bool,
|
||||||
|
onConfirm: PropTypes.func,
|
||||||
|
onReject: PropTypes.func,
|
||||||
|
origin: PropTypes.any,
|
||||||
|
status: PropTypes.string
|
||||||
|
};
|
||||||
|
|
||||||
|
static defaultProps = {
|
||||||
|
focus: false,
|
||||||
|
origin: {
|
||||||
|
type: 'unknown',
|
||||||
|
details: ''
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
componentWillMount () {
|
||||||
|
const { address, signerStore } = this.props;
|
||||||
|
|
||||||
|
signerStore.fetchBalance(address);
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
const { className } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={ `${styles.container} ${className}` }>
|
||||||
|
{ this.renderDetails() }
|
||||||
|
{ this.renderActions() }
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderDetails () {
|
||||||
|
const { api } = this.context;
|
||||||
|
const { address, data, netVersion, origin, signerStore } = this.props;
|
||||||
|
const { balances, externalLink } = signerStore;
|
||||||
|
|
||||||
|
const balance = balances[address];
|
||||||
|
|
||||||
|
if (!balance) {
|
||||||
|
return <div />;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={ styles.signDetails }>
|
||||||
|
<div className={ styles.address }>
|
||||||
|
<Account
|
||||||
|
address={ address }
|
||||||
|
balance={ balance }
|
||||||
|
className={ styles.account }
|
||||||
|
externalLink={ externalLink }
|
||||||
|
netVersion={ netVersion }
|
||||||
|
/>
|
||||||
|
<RequestOrigin origin={ origin } />
|
||||||
|
</div>
|
||||||
|
<div className={ styles.info } title={ api.util.sha3(data) }>
|
||||||
|
<p>
|
||||||
|
<FormattedMessage
|
||||||
|
id='signer.decryptRequest.request'
|
||||||
|
defaultMessage='A request to decrypt data using your account:'
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div className={ styles.signData }>
|
||||||
|
<p>{ data }</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderActions () {
|
||||||
|
const { accounts, address, focus, isFinished, status } = this.props;
|
||||||
|
const account = accounts[address];
|
||||||
|
|
||||||
|
if (isFinished) {
|
||||||
|
if (status === 'confirmed') {
|
||||||
|
return (
|
||||||
|
<div className={ styles.actions }>
|
||||||
|
<span className={ styles.isConfirmed }>
|
||||||
|
<FormattedMessage
|
||||||
|
id='signer.decryptRequest.state.confirmed'
|
||||||
|
defaultMessage='Confirmed'
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={ styles.actions }>
|
||||||
|
<span className={ styles.isRejected }>
|
||||||
|
<FormattedMessage
|
||||||
|
id='signer.decryptRequest.state.rejected'
|
||||||
|
defaultMessage='Rejected'
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TransactionPendingForm
|
||||||
|
account={ account }
|
||||||
|
address={ address }
|
||||||
|
focus={ focus }
|
||||||
|
isSending={ this.props.isSending }
|
||||||
|
netVersion={ this.props.netVersion }
|
||||||
|
onConfirm={ this.onConfirm }
|
||||||
|
onReject={ this.onReject }
|
||||||
|
className={ styles.actions }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
onConfirm = (data) => {
|
||||||
|
const { id } = this.props;
|
||||||
|
const { password } = data;
|
||||||
|
|
||||||
|
this.props.onConfirm({ id, password });
|
||||||
|
}
|
||||||
|
|
||||||
|
onReject = () => {
|
||||||
|
this.props.onReject(this.props.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapStateToProps (state) {
|
||||||
|
const { accounts } = state.personal;
|
||||||
|
|
||||||
|
return {
|
||||||
|
accounts
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
null
|
||||||
|
)(DecryptRequest);
|
17
js/src/views/Signer/components/DecryptRequest/index.js
Normal file
17
js/src/views/Signer/components/DecryptRequest/index.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
export default from './decryptRequest';
|
@ -33,7 +33,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.hash {
|
.hash {
|
||||||
margin-left: .2em;
|
margin-left: .5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hash, .url {
|
.hash, .url {
|
||||||
|
@ -16,8 +16,9 @@
|
|||||||
|
|
||||||
import React, { Component, PropTypes } from 'react';
|
import React, { Component, PropTypes } from 'react';
|
||||||
|
|
||||||
import TransactionPending from '../TransactionPending';
|
import DecryptRequest from '../DecryptRequest';
|
||||||
import SignRequest from '../SignRequest';
|
import SignRequest from '../SignRequest';
|
||||||
|
import TransactionPending from '../TransactionPending';
|
||||||
|
|
||||||
export default class RequestPending extends Component {
|
export default class RequestPending extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
@ -32,6 +33,7 @@ export default class RequestPending extends Component {
|
|||||||
onReject: PropTypes.func.isRequired,
|
onReject: PropTypes.func.isRequired,
|
||||||
origin: PropTypes.object.isRequired,
|
origin: PropTypes.object.isRequired,
|
||||||
payload: PropTypes.oneOfType([
|
payload: PropTypes.oneOfType([
|
||||||
|
PropTypes.shape({ decrypt: PropTypes.object.isRequired }),
|
||||||
PropTypes.shape({ sendTransaction: PropTypes.object.isRequired }),
|
PropTypes.shape({ sendTransaction: PropTypes.object.isRequired }),
|
||||||
PropTypes.shape({ sign: PropTypes.object.isRequired }),
|
PropTypes.shape({ sign: PropTypes.object.isRequired }),
|
||||||
PropTypes.shape({ signTransaction: PropTypes.object.isRequired })
|
PropTypes.shape({ signTransaction: PropTypes.object.isRequired })
|
||||||
@ -68,6 +70,27 @@ export default class RequestPending extends Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (payload.decrypt) {
|
||||||
|
const { decrypt } = payload;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DecryptRequest
|
||||||
|
address={ decrypt.address }
|
||||||
|
className={ className }
|
||||||
|
focus={ focus }
|
||||||
|
data={ decrypt.msg }
|
||||||
|
id={ id }
|
||||||
|
isFinished={ false }
|
||||||
|
isSending={ isSending }
|
||||||
|
netVersion={ netVersion }
|
||||||
|
onConfirm={ this.onConfirm }
|
||||||
|
onReject={ onReject }
|
||||||
|
origin={ origin }
|
||||||
|
signerStore={ signerStore }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const transaction = payload.sendTransaction || payload.signTransaction;
|
const transaction = payload.sendTransaction || payload.signTransaction;
|
||||||
|
|
||||||
if (transaction) {
|
if (transaction) {
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
.container {
|
.container {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 1.5em 0 1em;
|
padding: 1.5em 1em 1.5em 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.actions, .signDetails {
|
.actions, .signDetails {
|
||||||
@ -29,10 +29,11 @@
|
|||||||
|
|
||||||
.signData {
|
.signData {
|
||||||
border: 0.25em solid red;
|
border: 0.25em solid red;
|
||||||
|
margin-left: 2em;
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
margin-left: -2em;
|
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
max-height: 6em;
|
max-height: 6em;
|
||||||
|
max-width: calc(100% - 2em);
|
||||||
}
|
}
|
||||||
|
|
||||||
.signData > p {
|
.signData > p {
|
||||||
@ -40,23 +41,30 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.signDetails {
|
.signDetails {
|
||||||
flex: 10;
|
flex: 1;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.account img {
|
||||||
|
display: inline-block;
|
||||||
|
height: 50px;
|
||||||
|
margin: 5px;
|
||||||
|
width: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.address, .info {
|
.address, .info {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 50%;
|
vertical-align: top;
|
||||||
}
|
}
|
||||||
|
|
||||||
.address {
|
.address {
|
||||||
padding-right: $accountPadding;
|
width: 40%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.info {
|
.info {
|
||||||
padding: 0 30px;
|
|
||||||
color: #E53935;
|
color: #E53935;
|
||||||
vertical-align: top;
|
width: 60%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.info p:first-child {
|
.info p:first-child {
|
||||||
@ -81,10 +89,3 @@
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
min-height: $finishedHeight;
|
min-height: $finishedHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
.signDetails img {
|
|
||||||
display: inline-block;
|
|
||||||
width: 50px;
|
|
||||||
height: 50px;
|
|
||||||
margin: 5px;
|
|
||||||
}
|
|
||||||
|
@ -123,6 +123,7 @@ class SignRequest extends Component {
|
|||||||
<Account
|
<Account
|
||||||
address={ address }
|
address={ address }
|
||||||
balance={ balance }
|
balance={ balance }
|
||||||
|
className={ styles.account }
|
||||||
externalLink={ externalLink }
|
externalLink={ externalLink }
|
||||||
netVersion={ netVersion }
|
netVersion={ netVersion }
|
||||||
/>
|
/>
|
||||||
@ -155,9 +156,7 @@ class SignRequest extends Component {
|
|||||||
|
|
||||||
renderActions () {
|
renderActions () {
|
||||||
const { accounts, address, focus, isFinished, status } = this.props;
|
const { accounts, address, focus, isFinished, status } = this.props;
|
||||||
const account = Object
|
const account = accounts[address];
|
||||||
.values(accounts)
|
|
||||||
.find((account) => address === account.address.toLowerCase());
|
|
||||||
|
|
||||||
if (isFinished) {
|
if (isFinished) {
|
||||||
if (status === 'confirmed') {
|
if (status === 'confirmed') {
|
||||||
@ -191,6 +190,7 @@ class SignRequest extends Component {
|
|||||||
address={ address }
|
address={ address }
|
||||||
focus={ focus }
|
focus={ focus }
|
||||||
isSending={ this.props.isSending }
|
isSending={ this.props.isSending }
|
||||||
|
netVersion={ this.props.netVersion }
|
||||||
onConfirm={ this.onConfirm }
|
onConfirm={ this.onConfirm }
|
||||||
onReject={ this.onReject }
|
onReject={ this.onReject }
|
||||||
className={ styles.actions }
|
className={ styles.actions }
|
||||||
|
Loading…
Reference in New Issue
Block a user