1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-23 09:52:26 +01:00

Split ExportPrivateKeyModal into container and component files (#7561)

This commit is contained in:
Whymarrh Whitby 2019-11-27 11:36:31 -03:30 committed by GitHub
parent 00060d787a
commit f0e5ab6c12
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 208 additions and 179 deletions

View File

@ -1,178 +0,0 @@
const log = require('loglevel')
const Component = require('react').Component
const PropTypes = require('prop-types')
const h = require('react-hyperscript')
const inherits = require('util').inherits
const connect = require('react-redux').connect
const { stripHexPrefix } = require('ethereumjs-util')
const actions = require('../../../store/actions')
const { getSelectedIdentity } = require('../../../selectors/selectors')
const ReadOnlyInput = require('../../ui/readonly-input')
const copyToClipboard = require('copy-to-clipboard')
const { checksumAddress } = require('../../../helpers/utils/util')
import AccountModalContainer from './account-modal-container'
import Button from '../../ui/button'
function mapStateToPropsFactory () {
let selectedIdentity = null
return function mapStateToProps (state) {
// We should **not** change the identity displayed here even if it changes from underneath us.
// If we do, we will be showing the user one private key and a **different** address and name.
// Note that the selected identity **will** change from underneath us when we unlock the keyring
// which is the expected behavior that we are side-stepping.
selectedIdentity = selectedIdentity || getSelectedIdentity(state)
return {
warning: state.appState.warning,
privateKey: state.appState.accountDetail.privateKey,
network: state.metamask.network,
selectedIdentity,
previousModalState: state.appState.modal.previousModalState.name,
}
}
}
function mapDispatchToProps (dispatch) {
return {
exportAccount: (password, address) => {
return dispatch(actions.exportAccount(password, address))
.then((res) => {
dispatch(actions.hideWarning())
return res
})
},
showAccountDetailModal: () => dispatch(actions.showModal({ name: 'ACCOUNT_DETAILS' })),
hideModal: () => dispatch(actions.hideModal()),
}
}
inherits(ExportPrivateKeyModal, Component)
function ExportPrivateKeyModal () {
Component.call(this)
this.state = {
password: '',
privateKey: null,
showWarning: true,
}
}
ExportPrivateKeyModal.contextTypes = {
t: PropTypes.func,
}
module.exports = connect(mapStateToPropsFactory, mapDispatchToProps)(ExportPrivateKeyModal)
ExportPrivateKeyModal.prototype.exportAccountAndGetPrivateKey = function (password, address) {
const { exportAccount } = this.props
exportAccount(password, address)
.then(privateKey => this.setState({
privateKey,
showWarning: false,
}))
.catch((e) => log.error(e))
}
ExportPrivateKeyModal.prototype.renderPasswordLabel = function (privateKey) {
return h('span.private-key-password-label', privateKey
? this.context.t('copyPrivateKey')
: this.context.t('typePassword')
)
}
ExportPrivateKeyModal.prototype.renderPasswordInput = function (privateKey) {
const plainKey = privateKey && stripHexPrefix(privateKey)
return privateKey
? h(ReadOnlyInput, {
wrapperClass: 'private-key-password-display-wrapper',
inputClass: 'private-key-password-display-textarea',
textarea: true,
value: plainKey,
onClick: () => copyToClipboard(plainKey),
})
: h('input.private-key-password-input', {
type: 'password',
onChange: event => this.setState({ password: event.target.value }),
})
}
ExportPrivateKeyModal.prototype.renderButtons = function (privateKey, address, hideModal) {
return h('div.export-private-key-buttons', {}, [
!privateKey && h(Button, {
type: 'default',
large: true,
className: 'export-private-key__button export-private-key__button--cancel',
onClick: () => hideModal(),
}, this.context.t('cancel')),
(privateKey
? (
h(Button, {
type: 'secondary',
large: true,
className: 'export-private-key__button',
onClick: () => hideModal(),
}, this.context.t('done'))
) : (
h(Button, {
type: 'secondary',
large: true,
className: 'export-private-key__button',
disabled: !this.state.password,
onClick: () => this.exportAccountAndGetPrivateKey(this.state.password, address),
}, this.context.t('confirm'))
)
),
])
}
ExportPrivateKeyModal.prototype.render = function () {
const {
selectedIdentity,
warning,
showAccountDetailModal,
hideModal,
previousModalState,
} = this.props
const { name, address } = selectedIdentity
const {
privateKey,
showWarning,
} = this.state
return h(AccountModalContainer, {
selectedIdentity,
showBackButton: previousModalState === 'ACCOUNT_DETAILS',
backButtonAction: () => showAccountDetailModal(),
}, [
h('span.account-name', name),
h(ReadOnlyInput, {
wrapperClass: 'ellip-address-wrapper',
inputClass: 'qr-ellip-address ellip-address',
value: checksumAddress(address),
}),
h('div.account-modal-divider'),
h('span.modal-body-title', this.context.t('showPrivateKeys')),
h('div.private-key-password', {}, [
this.renderPasswordLabel(privateKey),
this.renderPasswordInput(privateKey),
showWarning && warning ? h('span.private-key-password-error', warning) : null,
]),
h('div.private-key-password-warning', this.context.t('privateKeyWarning')),
this.renderButtons(privateKey, address, hideModal),
])
}

View File

@ -0,0 +1,168 @@
import log from 'loglevel'
import PropTypes from 'prop-types'
import React, { Component } from 'react'
const { stripHexPrefix } = require('ethereumjs-util')
const copyToClipboard = require('copy-to-clipboard')
const { checksumAddress } = require('../../../../helpers/utils/util')
const ReadOnlyInput = require('../../../ui/readonly-input')
import Button from '../../../ui/button'
import AccountModalContainer from '../account-modal-container'
export default class ExportPrivateKeyModal extends Component {
static contextTypes = {
t: PropTypes.func,
}
static defaultProps = {
warning: null,
previousModalState: null,
}
static propTypes = {
exportAccount: PropTypes.func.isRequired,
selectedIdentity: PropTypes.object.isRequired,
warning: PropTypes.node,
showAccountDetailModal: PropTypes.func.isRequired,
hideModal: PropTypes.func.isRequired,
previousModalState: PropTypes.string,
}
state = {
password: '',
privateKey: null,
showWarning: true,
}
exportAccountAndGetPrivateKey = (password, address) => {
const { exportAccount } = this.props
exportAccount(password, address)
.then(privateKey => this.setState({
privateKey,
showWarning: false,
}))
.catch((e) => log.error(e))
}
renderPasswordLabel (privateKey) {
return (
<span className="private-key-password-label">
{
privateKey
? this.context.t('copyPrivateKey')
: this.context.t('typePassword')
}
</span>
)
}
renderPasswordInput (privateKey) {
const plainKey = privateKey && stripHexPrefix(privateKey)
if (!privateKey) {
return (
<input
type="password"
className="private-key-password-input"
onChange={event => this.setState({ password: event.target.value })}
/>
)
}
return (
<ReadOnlyInput
wrapperClass="private-key-password-display-wrapper"
inputClass="private-key-password-display-textarea"
textarea
value={plainKey}
onClick={() => copyToClipboard(plainKey)}
/>
)
}
renderButtons (privateKey, address, hideModal) {
return (
<div className="export-private-key-buttons">
{!privateKey && (
<Button
type="default"
large
className="export-private-key__button export-private-key__button--cancel"
onClick={() => hideModal()}
>
{this.context.t('cancel')}
</Button>
)}
{
privateKey
? (
<Button
onClick={() => hideModal()}
type="secondary"
large
className="export-private-key__button"
>
{this.context.t('done')}
</Button>
)
: (
<Button
onClick={() => this.exportAccountAndGetPrivateKey(this.state.password, address)}
type="secondary"
large
className="export-private-key__button"
disabled={!this.state.password}
>
{this.context.t('confirm')}
</Button>
)
}
</div>
)
}
render () {
const {
selectedIdentity,
warning,
showAccountDetailModal,
hideModal,
previousModalState,
} = this.props
const { name, address } = selectedIdentity
const {
privateKey,
showWarning,
} = this.state
return (
<AccountModalContainer
selectedIdentity={selectedIdentity}
showBackButton={previousModalState === 'ACCOUNT_DETAILS'}
backButtonAction={() => showAccountDetailModal()}
>
<span className="account-name">{name}</span>
<ReadOnlyInput
wrapperClass="ellip-address-wrapper"
inputClass="qr-ellip-address ellip-address"
value={checksumAddress(address)}
/>
<div className="account-modal-divider"/>
<span className="modal-body-title">{this.context.t('showPrivateKeys')}</span>
<div className="private-key-password">
{this.renderPasswordLabel(privateKey)}
{this.renderPasswordInput(privateKey)}
{
(showWarning && warning)
? <span className="private-key-password-error">{warning}</span>
: null
}
</div>
<div className="private-key-password-warning">{this.context.t('privateKeyWarning')}</div>
{this.renderButtons(privateKey, address, hideModal)}
</AccountModalContainer>
)
}
}

View File

@ -0,0 +1,38 @@
import { connect } from 'react-redux'
import { exportAccount, hideWarning, showModal, hideModal } from '../../../../store/actions'
import { getSelectedIdentity } from '../../../../selectors/selectors'
import ExportPrivateKeyModal from './export-private-key-modal.component'
function mapStateToPropsFactory () {
let selectedIdentity = null
return function mapStateToProps (state) {
// We should **not** change the identity displayed here even if it changes from underneath us.
// If we do, we will be showing the user one private key and a **different** address and name.
// Note that the selected identity **will** change from underneath us when we unlock the keyring
// which is the expected behavior that we are side-stepping.
selectedIdentity = selectedIdentity || getSelectedIdentity(state)
return {
warning: state.appState.warning,
privateKey: state.appState.accountDetail.privateKey,
network: state.metamask.network,
selectedIdentity,
previousModalState: state.appState.modal.previousModalState.name,
}
}
}
function mapDispatchToProps (dispatch) {
return {
exportAccount: (password, address) => {
return dispatch(exportAccount(password, address))
.then((res) => {
dispatch(hideWarning())
return res
})
},
showAccountDetailModal: () => dispatch(showModal({ name: 'ACCOUNT_DETAILS' })),
hideModal: () => dispatch(hideModal()),
}
}
export default connect(mapStateToPropsFactory, mapDispatchToProps)(ExportPrivateKeyModal)

View File

@ -0,0 +1 @@
export { default } from './export-private-key-modal.container'

View File

@ -12,7 +12,7 @@ const { ENVIRONMENT_TYPE_POPUP } = require('../../../../../app/scripts/lib/enums
// Modal Components
const DepositEtherModal = require('./deposit-ether-modal')
import AccountDetailsModal from './account-details-modal'
const ExportPrivateKeyModal = require('./export-private-key-modal')
const ExportPrivateKeyModal = require('./export-private-key-modal').default
const HideTokenConfirmationModal = require('./hide-token-confirmation-modal')
const NotifcationModal = require('./notification-modal')
const QRScanner = require('./qr-scanner')