From 0aaf236ad11f766c5ebd352d6fd22cdc9413542e Mon Sep 17 00:00:00 2001 From: Nicolas Gotchac Date: Mon, 10 Apr 2017 05:21:06 -0400 Subject: [PATCH] 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 --- js/src/api/format/output.js | 16 ++ .../DecryptRequest/decryptRequest.js | 183 ++++++++++++++++++ .../Signer/components/DecryptRequest/index.js | 17 ++ .../RequestOrigin/requestOrigin.css | 2 +- .../RequestPending/requestPending.js | 25 ++- .../components/SignRequest/signRequest.css | 39 ++-- .../components/SignRequest/signRequest.js | 6 +- 7 files changed, 264 insertions(+), 24 deletions(-) create mode 100644 js/src/views/Signer/components/DecryptRequest/decryptRequest.js create mode 100644 js/src/views/Signer/components/DecryptRequest/index.js diff --git a/js/src/api/format/output.js b/js/src/api/format/output.js index 8f375e210..df40b59a0 100644 --- a/js/src/api/format/output.js +++ b/js/src/api/format/output.js @@ -216,6 +216,8 @@ export function outSignerRequest (request) { break; 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].sendTransaction = outTransaction(request[key].sendTransaction); break; @@ -296,6 +298,20 @@ export function outTransaction (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) { if (trace) { if (trace.action) { diff --git a/js/src/views/Signer/components/DecryptRequest/decryptRequest.js b/js/src/views/Signer/components/DecryptRequest/decryptRequest.js new file mode 100644 index 000000000..f4626c755 --- /dev/null +++ b/js/src/views/Signer/components/DecryptRequest/decryptRequest.js @@ -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 . + +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 ( +
+ { this.renderDetails() } + { this.renderActions() } +
+ ); + } + + renderDetails () { + const { api } = this.context; + const { address, data, netVersion, origin, signerStore } = this.props; + const { balances, externalLink } = signerStore; + + const balance = balances[address]; + + if (!balance) { + return
; + } + + return ( +
+
+ + +
+
+

+ +

+ +
+

{ data }

+
+
+
+ ); + } + + renderActions () { + const { accounts, address, focus, isFinished, status } = this.props; + const account = accounts[address]; + + if (isFinished) { + if (status === 'confirmed') { + return ( +
+ + + +
+ ); + } + + return ( +
+ + + +
+ ); + } + + return ( + + ); + } + + 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); diff --git a/js/src/views/Signer/components/DecryptRequest/index.js b/js/src/views/Signer/components/DecryptRequest/index.js new file mode 100644 index 000000000..c2bc5e1e9 --- /dev/null +++ b/js/src/views/Signer/components/DecryptRequest/index.js @@ -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 . + +export default from './decryptRequest'; diff --git a/js/src/views/Signer/components/RequestOrigin/requestOrigin.css b/js/src/views/Signer/components/RequestOrigin/requestOrigin.css index f4aac4c48..f5717e10c 100644 --- a/js/src/views/Signer/components/RequestOrigin/requestOrigin.css +++ b/js/src/views/Signer/components/RequestOrigin/requestOrigin.css @@ -33,7 +33,7 @@ } .hash { - margin-left: .2em; + margin-left: .5em; } .hash, .url { diff --git a/js/src/views/Signer/components/RequestPending/requestPending.js b/js/src/views/Signer/components/RequestPending/requestPending.js index 3d8ea0c15..7865a1d77 100644 --- a/js/src/views/Signer/components/RequestPending/requestPending.js +++ b/js/src/views/Signer/components/RequestPending/requestPending.js @@ -16,8 +16,9 @@ import React, { Component, PropTypes } from 'react'; -import TransactionPending from '../TransactionPending'; +import DecryptRequest from '../DecryptRequest'; import SignRequest from '../SignRequest'; +import TransactionPending from '../TransactionPending'; export default class RequestPending extends Component { static propTypes = { @@ -32,6 +33,7 @@ export default class RequestPending extends Component { onReject: PropTypes.func.isRequired, origin: PropTypes.object.isRequired, payload: PropTypes.oneOfType([ + PropTypes.shape({ decrypt: PropTypes.object.isRequired }), PropTypes.shape({ sendTransaction: PropTypes.object.isRequired }), PropTypes.shape({ sign: 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 ( + + ); + } + const transaction = payload.sendTransaction || payload.signTransaction; if (transaction) { diff --git a/js/src/views/Signer/components/SignRequest/signRequest.css b/js/src/views/Signer/components/SignRequest/signRequest.css index b26932e19..a8b3ddd6d 100644 --- a/js/src/views/Signer/components/SignRequest/signRequest.css +++ b/js/src/views/Signer/components/SignRequest/signRequest.css @@ -19,7 +19,7 @@ .container { display: flex; - padding: 1.5em 0 1em; + padding: 1.5em 1em 1.5em 0; } .actions, .signDetails { @@ -28,35 +28,43 @@ } .signData { - border: 0.25em solid red; - padding: 0.5em; - margin-left: -2em; - overflow: auto; - max-height: 6em; + border: 0.25em solid red; + margin-left: 2em; + padding: 0.5em; + overflow: auto; + max-height: 6em; + max-width: calc(100% - 2em); } .signData > p { - color: white; + color: white; } .signDetails { - flex: 10; + flex: 1; + overflow: auto; +} + +.account img { + display: inline-block; + height: 50px; + margin: 5px; + width: 50px; } .address, .info { box-sizing: border-box; display: inline-block; - width: 50%; + vertical-align: top; } .address { - padding-right: $accountPadding; + width: 40%; } .info { - padding: 0 30px; color: #E53935; - vertical-align: top; + width: 60%; } .info p:first-child { @@ -81,10 +89,3 @@ display: inline-block; min-height: $finishedHeight; } - -.signDetails img { - display: inline-block; - width: 50px; - height: 50px; - margin: 5px; -} diff --git a/js/src/views/Signer/components/SignRequest/signRequest.js b/js/src/views/Signer/components/SignRequest/signRequest.js index ef68e78a1..624e0931f 100644 --- a/js/src/views/Signer/components/SignRequest/signRequest.js +++ b/js/src/views/Signer/components/SignRequest/signRequest.js @@ -123,6 +123,7 @@ class SignRequest extends Component { @@ -155,9 +156,7 @@ class SignRequest extends Component { renderActions () { const { accounts, address, focus, isFinished, status } = this.props; - const account = Object - .values(accounts) - .find((account) => address === account.address.toLowerCase()); + const account = accounts[address]; if (isFinished) { if (status === 'confirmed') { @@ -191,6 +190,7 @@ class SignRequest extends Component { address={ address } focus={ focus } isSending={ this.props.isSending } + netVersion={ this.props.netVersion } onConfirm={ this.onConfirm } onReject={ this.onReject } className={ styles.actions }