Skip to content

Commit

Permalink
Extract PasswordField component from FromPrivateKey
Browse files Browse the repository at this point in the history
  • Loading branch information
lukaw3d committed Sep 22, 2022
1 parent 11f67e8 commit 9a77a7b
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 31 deletions.
11 changes: 7 additions & 4 deletions cypress/integration/open-wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,19 +75,22 @@ describe('Open wallet', () => {
})

it('Should reject invalid keys', () => {
cy.findByTestId('privatekey').type('this is an invalid key')
cy.findByPlaceholderText('Enter your private key here').type('this is an invalid key')
cy.findByRole('button', { name: /Import my wallet/ }).click()
cy.findByText(/Invalid private key/).should('be.visible')
})

it('Should reject invalid keys, even if base64 seems to be OK', () => {
cy.findByTestId('privatekey').type('aaamZybIOymrQCpCGGICczsaopANP02kwOhCyxETXljLLmRChL1QJGzJq3Pf3i+dFBN+peIK2vQ3Ew0wSQbp3g==')
cy.findByPlaceholderText('Enter your private key here').type(
'aaamZybIOymrQCpCGGICczsaopANP02kwOhCyxETXljLLmRChL1QJGzJq3Pf3i+dFBN+peIK2vQ3Ew0wSQbp3g==',
{ delay: 1 },
)
cy.findByRole('button', { name: /Import my wallet/ }).click()
cy.findByText(/Invalid private key/).should('be.visible')
})

it('Should accept valid base64 pkey', () => {
cy.findByTestId('privatekey').type(privateKey, { delay: 1 })
cy.findByPlaceholderText('Enter your private key here').type(privateKey, { delay: 1 })
cy.findByRole('button', { name: /Import my wallet/ }).click()
cy.findByText(/Invalid private key/).should('not.exist')
cy.url().should('include', '/account/oasis1qz0k5q8vjqvu4s4nwxyj406ylnflkc4vrcjghuwk')
Expand All @@ -97,7 +100,7 @@ describe('Open wallet', () => {
cy.findByRole('button', { name: /Open wallet/ }).click()
cy.findByRole('button', { name: /Private key/ }).click()
cy.url().should('include', '/open-wallet/private-key')
cy.findByTestId('privatekey').type(privateKey, { delay: 1 })
cy.findByPlaceholderText('Enter your private key here').type(privateKey, { delay: 1 })
cy.findByRole('button', { name: /Import my wallet/ }).click()
cy.url().should('include', '/account/oasis1qz0k5q8vjqvu4s4nwxyj406ylnflkc4vrcjghuwk')
})
Expand Down
2 changes: 1 addition & 1 deletion cypress/integration/scenario-account-switcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ describe('Scenario : multiple accounts', () => {
// Open account 2 through private
cy.findByRole('button', { name: /Open wallet/ }).click()
cy.findByRole('button', { name: /Private key/ }).click()
cy.findByTestId('privatekey').type(
cy.findByPlaceholderText('Enter your private key here').type(
'X0jlpvskP1q8E6rHxWRJr7yTvpCuOPEKBGW8gtuVTxfnViTI0s2fBizgMxNzo75Q7w7MxdJXtOLeqDoFUGxxMg==',
{ delay: 0 },
)
Expand Down
2 changes: 1 addition & 1 deletion cypress/integration/scenario-transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ describe('Scenario : from private key', () => {
cy.visit('/')
cy.findByRole('button', { name: /Open wallet/ }).click()
cy.findByRole('button', { name: /Private key/ }).click()
cy.findByTestId('privatekey').type(
cy.findByPlaceholderText('Enter your private key here').type(
'X0jlpvskP1q8E6rHxWRJr7yTvpCuOPEKBGW8gtuVTxfnViTI0s2fBizgMxNzo75Q7w7MxdJXtOLeqDoFUGxxMg==',
{ delay: 1 },
)
Expand Down
51 changes: 31 additions & 20 deletions src/app/components/PasswordField/index.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,44 @@
export function PasswordField() {
import { Box, FormField, Button, TextInput, Tip } from 'grommet'
import { View, Hide } from 'grommet-icons/icons'
import * as React from 'react'

interface Props {
value: string
onChange: (event: React.ChangeEvent<HTMLInputElement>) => void
error: string | false
inputElementId: string
placeholder: string
showTip: string
hideTip: string

width: string
}

export function PasswordField(props: Props) {
const [passwordIsVisible, setPasswordIsVisible] = React.useState(false)

return (
<FormField
htmlFor="privateKey"
error={privateKeyIsValid === false ? t('openWallet.privateKey.error', 'Invalid private key') : ''}
htmlFor={props.inputElementId}
error={props.error ? props.error : ''}
border
contentProps={{ border: privateKeyIsValid ? false : 'bottom' }}
contentProps={{ border: props.error ? 'bottom' : false }}
round="small"
width="xlarge"
width={props.width}
>
<Box direction="row" align="center">
<TextInput
id="privatekey"
data-testid="privatekey"
placeholder={t('openWallet.privateKey.enterPrivateKeyHere', 'Enter your private key here')}
value={privateKey}
onChange={onChange}
type={privateKeyIsVisible ? 'text' : 'password'}
id={props.inputElementId}
placeholder={props.placeholder}
value={props.value}
onChange={props.onChange}
type={passwordIsVisible ? 'text' : 'password'}
plain
/>
<Tip
content={
privateKeyIsVisible
? t('openWallet.privateKey.hidePrivateKey', 'Hide private key')
: t('openWallet.privateKey.showPrivateKey', 'Show private key')
}
>
<Tip content={passwordIsVisible ? props.hideTip : props.showTip}>
<Button
onClick={() => setPrivateKeyIsVisible(!privateKeyIsVisible)}
icon={privateKeyIsVisible ? <View /> : <Hide />}
onClick={() => setPasswordIsVisible(!passwordIsVisible)}
icon={passwordIsVisible ? <View /> : <Hide />}
/>
</Tip>
</Box>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,6 @@ exports[`<FromPrivateKey /> should match snapshot 1`] = `
<input
autocomplete="off"
class="c8"
data-testid="privatekey"
id="privatekey"
placeholder="openWallet.privateKey.enterPrivateKeyHere"
type="password"
Expand Down
18 changes: 14 additions & 4 deletions src/app/pages/OpenWalletPage/Features/FromPrivateKey/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { walletActions } from 'app/state/wallet'
import { Box, Form, Heading, Paragraph, FormField, Button, TextInput, Tip } from 'grommet'
import { View, Hide } from 'grommet-icons/icons'
import { Box, Form, Heading, Paragraph, Button } from 'grommet'
import * as React from 'react'
import { useDispatch } from 'react-redux'
import { OasisKey } from 'app/lib/key'
import { base64ToUint, uint2hex } from 'app/lib/helpers'
import { useTranslation } from 'react-i18next'
import { PasswordField } from 'app/components/PasswordField'

interface Props {}

Expand All @@ -26,7 +26,6 @@ export function FromPrivateKey(props: Props) {

const [privateKey, setPrivateKey] = React.useState('')
const [privateKeyIsValid, setPrivateKeyIsValid] = React.useState(true)
const [privateKeyIsVisible, setPrivateKeyIsVisible] = React.useState(false)

const onChange = (event: React.ChangeEvent<HTMLInputElement>) => setPrivateKey(event.target.value)
const onSubmit = () => {
Expand Down Expand Up @@ -54,7 +53,18 @@ export function FromPrivateKey(props: Props) {
{t('openWallet.privateKey.instruction', 'Enter your private key in Base64 format.')}
</label>
</Paragraph>
<PasswordField></PasswordField>

<PasswordField
value={privateKey}
onChange={onChange}
error={privateKeyIsValid ? false : t('openWallet.privateKey.error', 'Invalid private key')}
inputElementId="privatekey"
placeholder={t('openWallet.privateKey.enterPrivateKeyHere', 'Enter your private key here')}
hideTip={t('openWallet.privateKey.hidePrivateKey', 'Hide private key')}
showTip={t('openWallet.privateKey.showPrivateKey', 'Show private key')}
width="xlarge"
></PasswordField>

<Box pad={{ vertical: 'medium' }}>
<Box direction="row" justify="between" margin={{ top: 'medium' }}>
<Button
Expand Down

0 comments on commit 9a77a7b

Please sign in to comment.