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

CU-2pjkxye - No visible QR code #2426

Merged
merged 2 commits into from
Sep 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions app/components/Panel/FullHeightPanel/FullHeightPanel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ export default class ViewLayout extends Component<Props> {
shouldRenderHeader: true,
renderInstructions: () => (
<div>
{' '}
<FormattedMessage id="walletCreationInstruction" />{' '}
<FormattedMessage id="walletCreationInstruction" />
</div>
),
iconColor: '#4CFFB3',
Expand Down Expand Up @@ -97,8 +96,7 @@ export default class ViewLayout extends Component<Props> {
return (
renderInstructions && (
<div className={classNames(styles.instructions, instructionsClassName)}>
{' '}
{renderInstructions()}{' '}
{renderInstructions()}
</div>
)
)
Expand Down
291 changes: 114 additions & 177 deletions app/components/Settings/EncryptForm/EncryptForm.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
// @flow
import React from 'react'
import { noop } from 'lodash-es'
import { FormattedMessage, intlShape } from 'react-intl'
import React, { useState, useEffect } from 'react'
import { useIntl } from 'react-intl'
import { wallet } from '@cityofzion/neon-js'
import { wallet as n3Wallet } from '@cityofzion/neon-js-next'

import Button from '../../Button'
import TextInput from '../../Inputs/TextInput'
Expand All @@ -11,208 +12,144 @@ import styles from './EncryptForm.scss'
import { MIN_PASSPHRASE_LEN } from '../../../core/wallet'

type Props = {
submitLabel: string,
formPrivateKey: string,
formPassphrase: string,
formConfirmPassphrase: string,
validatePassphraseLength: Function,
isWIF: Function,
onSubmit: Function,
intl: intlShape,
validatePassphraseLength(text: string): void,
setEncryptedWIF(encryptedWif: string): void,
chain: string,
}

type State = {
privateKeyError: string,
passphraseError: string,
confirmPassphraseError: string,
isDisabled: boolean,
privateKey: string,
passphrase: string,
confirmPassphrase: string,
}

export default class EncryptForm extends React.Component<Props, State> {
constructor(props: Props) {
super(props)

this.state = {
privateKeyError: '',
passphraseError: '',
confirmPassphraseError: '',
isDisabled: true,
privateKey: '',
passphrase: '',
confirmPassphrase: '',
}
}
const EncryptForm = ({
chain,
validatePassphraseLength,
setEncryptedWIF,
}: Props) => {
const intl = useIntl()

static defaultProps = {
submitLabel: 'Generate Encrypted key',
onSubmit: noop,
isWIF: noop,
validatePassphraseLength: noop,
}
const [privateKey, setPrivateKey] = useState('')
const [passphrase, setPassphrase] = useState('')
const [confirmPassphrase, setConfirmPassphrase] = useState('')
const [privateKeyError, setPrivateKeyError] = useState('')
const [passphraseError, setPassphraseError] = useState('')
const [confirmPassphraseError, setConfirmPassphraseError] = useState('')
const [isDisabled, setIsDisabled] = useState(true)

render() {
const {
submitLabel,
formPrivateKey,
formPassphrase,
formConfirmPassphrase,
intl,
} = this.props
const {
privateKeyError,
passphraseError,
confirmPassphraseError,
isDisabled,
} = this.state

return (
<section className={styles.formContainer}>
<form className={styles.encryptForm} onSubmit={this.handleSubmit}>
<TextInput
id="privateKey"
name="privateKey"
label={<FormattedMessage id="encryptStep1Label" />}
placeholder={intl.formatMessage({ id: 'encryptStep1Placeholder' })}
value={formPrivateKey}
onChange={this.handleChangePrivateKey}
error={privateKeyError}
/>
<PasswordInput
id="passphrase"
name="passphrase"
label={<FormattedMessage id="encryptStep2Label" />}
placeholder={intl.formatMessage({ id: 'encryptStep2Placeholder' })}
value={formPassphrase}
onChange={this.handleChangePassphrase}
error={passphraseError}
/>
<PasswordInput
id="confirmPassphrase"
name="confirmPassphrase"
label={<FormattedMessage id="encryptStep3Label" />}
placeholder={intl.formatMessage({ id: 'encryptStep3Placeholder' })}
value={formConfirmPassphrase}
onChange={this.handleChangeConfirmPassphrase}
error={confirmPassphraseError}
/>
<Button
className={styles.submitButton}
primary
type="submit"
renderIcon={AddIcon}
disabled={isDisabled}
>
{submitLabel}
</Button>
</form>
</section>
)
}
const validatePrivateKey = () => {
const isWIF = chain === 'neo3' ? n3Wallet.isWIF : wallet.isWIF

validatePrivateKey = (privateKey: string) => {
const { isWIF, intl } = this.props
if (privateKey && !isWIF(privateKey)) {
this.setState({
privateKeyError: intl.formatMessage({ id: 'errors.encrypt.valid' }),
})
setPrivateKeyError(intl.formatMessage({ id: 'errors.encrypt.valid' }))

return false
}

return true
}

validatePassphrase = (passphrase: string, confirmPassphrase: string) => {
const { validatePassphraseLength, intl } = this.props
if (passphrase !== confirmPassphrase) {
this.setState({
confirmPassphrase: intl.formatMessage({ id: 'errors.password.match' }),
})
return false
}

const validatePassphrase = () => {
if (!validatePassphraseLength(passphrase)) {
this.setState({
passphraseError: intl.formatMessage(
setPassphraseError(
intl.formatMessage(
{ id: 'errors.password.length' },
{ MIN_PASSPHRASE_LEN },
),
})
)
return false
}
return true
}

validate = (
privateKey: string,
passphrase: string,
confirmPassphrase: string,
) => {
const validPrivateKey = this.validatePrivateKey(privateKey)
const validatePassphrase = this.validatePassphrase(
passphrase,
confirmPassphrase,
)

return validPrivateKey && validatePassphrase
return true
}

clearErrors = (name: string) => {
if (name === 'passphrase' || name === 'confirmPassphrase') {
this.setState({ passphraseError: '' })
this.setState({ confirmPassphraseError: '' })
} else if (name === 'privateKey') {
this.setState({ privateKeyError: '' })
const validateConfirmPassphrase = () => {
if (passphrase !== confirmPassphrase) {
setConfirmPassphraseError(
intl.formatMessage({ id: 'errors.password.match' }),
)
return false
}
}

setButtonIsDisabled = (
privateKey: string,
passphrase: string,
confirmPassphrase: string,
) => {
this.setState({
isDisabled: !privateKey || !passphrase || !confirmPassphrase,
})
return true
}

handleChangePrivateKey = (event: Object) => {
const newPrivateKey = event.target.value
const { passphrase, confirmPassphrase } = this.state

this.setState({ privateKey: newPrivateKey })
this.clearErrors(event.target.name)
this.setButtonIsDisabled(newPrivateKey, passphrase, confirmPassphrase)
}
const handleSubmit = async event => {
event.preventDefault()

handleChangePassphrase = (event: Object) => {
const newPassphrase = event.target.value
const { privateKey, confirmPassphrase } = this.state
const privateKeyIsValid = validatePrivateKey()
const passphraseisValid = validatePassphrase()
const confirmPassphraseIsValid = validateConfirmPassphrase()

this.setState({ passphrase: newPassphrase })
this.clearErrors(event.target.name)
this.setButtonIsDisabled(privateKey, newPassphrase, confirmPassphrase)
}
if (!privateKeyIsValid || !passphraseisValid || !confirmPassphraseIsValid)
return

handleChangeConfirmPassphrase = (event: Object) => {
const newConfirmPassphrase = event.target.value
const { privateKey, passphrase } = this.state
const encryptedWIF =
chain === 'neo3'
? await n3Wallet.encrypt(privateKey, passphrase)
: wallet.encrypt(privateKey, passphrase)

this.setState({ confirmPassphrase: newConfirmPassphrase })
this.clearErrors(event.target.name)
this.setButtonIsDisabled(privateKey, passphrase, newConfirmPassphrase)
setEncryptedWIF(encryptedWIF)
}

handleSubmit = (event: Object) => {
event.preventDefault()
const { onSubmit } = this.props
const { privateKey, passphrase, confirmPassphrase } = this.state

const validInput = this.validate(privateKey, passphrase, confirmPassphrase)

if (!validInput) return

onSubmit(privateKey, passphrase, confirmPassphrase)
}
useEffect(
() => {
setIsDisabled(!privateKey || !passphrase || !confirmPassphrase)
},
[privateKey, passphrase, confirmPassphrase],
)

useEffect(
() => {
setPassphraseError('')
setConfirmPassphraseError('')
},
[passphrase, confirmPassphrase],
)

useEffect(
() => {
setPrivateKeyError('')
},
[privateKey],
)

return (
<section className={styles.formContainer}>
<form className={styles.encryptForm} onSubmit={handleSubmit}>
<TextInput
id="privateKey"
name="privateKey"
label={intl.formatMessage({ id: 'encryptStep1Label' })}
placeholder={intl.formatMessage({ id: 'encryptStep1Placeholder' })}
value={privateKey}
onChange={event => setPrivateKey(event.target.value)}
error={privateKeyError}
/>
<PasswordInput
id="passphrase"
name="passphrase"
label={intl.formatMessage({ id: 'encryptStep2Label' })}
placeholder={intl.formatMessage({ id: 'encryptStep2Placeholder' })}
value={passphrase}
onChange={event => setPassphrase(event.target.value)}
error={passphraseError}
/>
<PasswordInput
id="confirmPassphrase"
name="confirmPassphrase"
label={intl.formatMessage({ id: 'encryptStep3Label' })}
placeholder={intl.formatMessage({ id: 'encryptStep3Placeholder' })}
value={confirmPassphrase}
onChange={event => setConfirmPassphrase(event.target.value)}
error={confirmPassphraseError}
/>
<Button
primary
type="submit"
renderIcon={AddIcon}
disabled={isDisabled}
>
{intl.formatMessage({ id: 'encryptButton' })}
</Button>
</form>
</section>
)
}

export default EncryptForm
6 changes: 0 additions & 6 deletions app/components/Settings/EncryptForm/EncryptForm.scss
Original file line number Diff line number Diff line change
@@ -1,18 +1,12 @@
.encryptForm {
width: 500px;
margin: 0 auto;
height: 100%;
display: flex;
flex-direction: column;

form {
align-self: flex-start;
}

.submitButton {
margin-top: auto;
margin-bottom: 50px;
}
}

.formContainer {
Expand Down
25 changes: 23 additions & 2 deletions app/components/Settings/EncryptForm/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,25 @@
import { injectIntl } from 'react-intl'
import { compose, withProps } from 'recompose'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
import withChainData from '../../../hocs/withChainData'
import EncryptForm from './EncryptForm'
import { setEncryptedWIF } from '../../../modules/generateEncryptedWIF'
import { validatePassphraseLength } from '../../../core/wallet'

export default injectIntl(EncryptForm)
const actionCreators = {
setEncryptedWIF,
}

const mapDispatchToProps = dispatch =>
bindActionCreators(actionCreators, dispatch)

export default compose(
connect(
null,
mapDispatchToProps,
),
withChainData(),
withProps({
validatePassphraseLength,
}),
)(EncryptForm)
Loading